/WhereAbout/src/com/google/marvin/whereabout/WhereAbout.java

http://eyes-free.googlecode.com/ · Java · 253 lines · 173 code · 20 blank · 60 comment · 32 complexity · 908ac95651c49a78cf4ae1fba3aedd6f MD5 · raw file

  1. /*
  2. * Copyright (C) 2008 Google Inc.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  5. * use this file except in compliance with the License. You may obtain a copy
  6. * of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  12. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  13. * License for the specific language governing permissions and limitations
  14. * under the License.
  15. */
  16. package com.google.marvin.whereabout;
  17. import com.google.tts.TTS;
  18. import com.google.tts.TTS.InitListener;
  19. import android.app.Activity;
  20. import android.app.ProgressDialog;
  21. import android.content.Context;
  22. import android.location.Location;
  23. import android.location.LocationListener;
  24. import android.location.LocationManager;
  25. import android.location.LocationProvider;
  26. import android.os.Bundle;
  27. import android.os.Handler;
  28. import android.os.Message;
  29. import android.util.Log;
  30. import android.view.KeyEvent;
  31. import android.widget.TextView;
  32. /**
  33. * This activity allows the user to obtain the current street, address,
  34. * or intersection. The location is displayed on the screen as well as
  35. * spoken to the user.
  36. *
  37. * @author chaitanyag@google.com (Chaitanya Gharpure)
  38. *
  39. */
  40. public class WhereAbout extends Activity implements Runnable {
  41. private ProgressDialog progressDiag = null;
  42. private TextView mainText = null;
  43. private LocationManager locationManager = null;
  44. private Location currentLocation = null;
  45. private TTS tts = null;
  46. private WhereAboutListener locListener = null;
  47. private boolean ttsLoaded = false;
  48. private long timeDown, pressTime;
  49. private float accuracy;
  50. /** Called when the activity is first created. */
  51. @Override
  52. public void onCreate(Bundle savedInstanceState) {
  53. super.onCreate(savedInstanceState);
  54. tts = new TTS(this, new InitListener() {
  55. public void onInit(int arg0) {
  56. ttsLoaded = true;
  57. }}, true);
  58. locationManager =
  59. (LocationManager) getSystemService(Context.LOCATION_SERVICE);
  60. this.locListener = new WhereAboutListener();
  61. locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
  62. 0, 0, locListener);
  63. locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,
  64. 0, 0, locListener);
  65. setContentView(R.layout.main);
  66. mainText = (TextView) findViewById(R.id.mainText);
  67. }
  68. /** Called when a key is pressed down */
  69. public boolean onKeyDown(int keyCode, KeyEvent event) {
  70. if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
  71. timeDown = System.currentTimeMillis();
  72. if (ttsLoaded) {
  73. tts.stop();
  74. }
  75. } else {
  76. super.onKeyDown(keyCode, event);
  77. }
  78. return false;
  79. }
  80. /** called when a key is released */
  81. public boolean onKeyUp(int keyCode, KeyEvent event) {
  82. if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
  83. pressTime = System.currentTimeMillis() - timeDown;
  84. progressDiag =
  85. ProgressDialog.show(this, getString(R.string.progress_title),
  86. getString(R.string.progress_msg), true, false);
  87. if (ttsLoaded) {
  88. tts.speak(getString(R.string.progress_msg), 0, null);
  89. }
  90. (new Thread(this)).start();
  91. } else {
  92. super.onKeyUp(keyCode, event);
  93. }
  94. return false;
  95. }
  96. public synchronized void run() {
  97. // if pressTime > 500: Long press: intersection
  98. // else Short press: absolute street address
  99. locate(pressTime > 500);
  100. }
  101. /**
  102. * Obtains the address and presents it to the user by appending
  103. * appropriate prefixes.
  104. * @param abs Whether the full street address was requested
  105. */
  106. private void locate(boolean abs) {
  107. Location loc = null;
  108. String prefix = "";
  109. loc = currentLocation;
  110. if (loc != null) {
  111. accuracy = loc.getAccuracy();
  112. if (accuracy < 10) { // Probably a GPS fix
  113. prefix = getString(R.string.abs_loc_prefix);
  114. } else if (accuracy < 200) { // Probably a Wifi fix
  115. prefix = getString(R.string.wifi_loc_prefix);
  116. } else { // Probably a Cell tower fix
  117. prefix = getString(R.string.nw_loc_prefix);
  118. }
  119. } else { // Cannot find a fix
  120. loc = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
  121. prefix = getString(R.string.unknown_loc_prefix) + " " +
  122. getString(R.string.prev_loc_prefix);
  123. }
  124. String address = null;
  125. String speakStr = "";
  126. if (abs) {
  127. address = getAbsAddress(loc);
  128. speakStr = prefix + " " + address;
  129. } else {
  130. address = getIntersection(loc);
  131. if (address.contains(" and ")) { // Intersection
  132. speakStr = prefix + " " + getString(R.string.insersection_prefix) +
  133. address;
  134. } else { // Not an intersection
  135. speakStr = prefix + " " + address;
  136. }
  137. }
  138. Bundle data = new Bundle();
  139. data.putString("address", address);
  140. data.putString("speakstr", speakStr);
  141. Message msg = new Message();
  142. msg.setData(data);
  143. handler.sendMessage(msg);
  144. }
  145. /**
  146. * Dismisses th progress dialog, and displays result.
  147. */
  148. private Handler handler = new Handler() {
  149. @Override
  150. public void handleMessage(Message msg) {
  151. progressDiag.dismiss();
  152. displayAndSpeak(msg.getData().getString("address"),
  153. msg.getData().getString("speakstr"));
  154. }
  155. };
  156. /**
  157. * Displays the specified string on the screen and speaks it.
  158. * @param dispStr The string to display
  159. * @param speakStr The string to speak
  160. */
  161. private void displayAndSpeak(String dispStr, String speakStr) {
  162. if (dispStr == null || speakStr == null) {
  163. return;
  164. }
  165. mainText.setText(dispStr);
  166. if (ttsLoaded) {
  167. Log.d("Locator", "Speaking: " + speakStr);
  168. tts.speak(speakStr, 0, null);
  169. }
  170. }
  171. /**
  172. * Obtains the reverse geocoded address for the specified location
  173. * @param currentLocation The location to reverse geocode
  174. * @return
  175. */
  176. private String getAbsAddress(Location loc) {
  177. String address =
  178. StreetLocator.getAddress(loc.getLatitude(), loc.getLongitude());
  179. if (address != null) {
  180. return address;
  181. } else {
  182. return getString(R.string.failed_abs);
  183. }
  184. }
  185. /**
  186. * Obtains the street names at the specified location.
  187. * @param currentLocation The location to find streets names at
  188. * @return
  189. */
  190. private String getIntersection(Location loc) {
  191. String[] addr =
  192. StreetLocator.getStreetIntersection(loc.getLatitude(),
  193. loc.getLongitude());
  194. String address = "";
  195. if (addr.length == 0) {
  196. return getString(R.string.failed_intersection);
  197. }
  198. for (String ad : addr) {
  199. address += ad + " and ";
  200. }
  201. address = address.substring(0, address.length() - 4);
  202. return address;
  203. }
  204. @Override
  205. public void onDestroy() {
  206. locationManager.removeUpdates(locListener);
  207. super.onDestroy();
  208. }
  209. /**
  210. * Listener to register for location updates.
  211. */
  212. private class WhereAboutListener implements LocationListener {
  213. /**
  214. * Called when the location changes.
  215. */
  216. public void onLocationChanged(Location arg0) {
  217. currentLocation = arg0;
  218. }
  219. /**
  220. * Called when the location provider's status changes.
  221. */
  222. public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
  223. if (arg1 != LocationProvider.AVAILABLE) {
  224. currentLocation = null;
  225. }
  226. }
  227. public void onProviderDisabled(String provider) {
  228. currentLocation = null;
  229. }
  230. public void onProviderEnabled(String provider) {
  231. }
  232. }
  233. }