/walkytalky/src/com/googlecode/eyesfree/walkytalky/NewLocationActivity.java

http://eyes-free.googlecode.com/ · Java · 433 lines · 337 code · 54 blank · 42 comment · 48 complexity · d57c290a53eeb1a48267657112217300 MD5 · raw file

  1. /*
  2. * Copyright (C) 2009 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 of
  6. * 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 under
  14. * the License.
  15. */
  16. /**
  17. * UI for launching WalkyTalky.
  18. *
  19. * @author clchen@google.com (Charles L. Chen), hiteshk@google.com (Hitesh Khandelwal)
  20. */
  21. package com.googlecode.eyesfree.walkytalky;
  22. import android.app.Activity;
  23. import android.app.AlertDialog;
  24. import android.content.DialogInterface;
  25. import android.content.Intent;
  26. import android.content.SharedPreferences;
  27. import android.content.SharedPreferences.Editor;
  28. import android.database.Cursor;
  29. import android.net.Uri;
  30. import android.os.Bundle;
  31. import android.preference.PreferenceManager;
  32. import android.provider.ContactsContract.CommonDataKinds.Phone;
  33. import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
  34. import android.speech.RecognizerIntent;
  35. import android.view.KeyEvent;
  36. import android.view.View;
  37. import android.view.View.OnClickListener;
  38. import android.view.View.OnKeyListener;
  39. import android.widget.ArrayAdapter;
  40. import android.widget.AutoCompleteTextView;
  41. import android.widget.Button;
  42. import java.util.ArrayList;
  43. import java.util.HashMap;
  44. import java.util.Iterator;
  45. import java.util.Map.Entry;
  46. /**
  47. * Allows users to search for new locations. Mark locations as favorite, browse
  48. * recent locations, delete locations from favorite. Returns (Lat, Lon) pair
  49. * corresponding to the searched address, to the caller Activity.
  50. */
  51. public class NewLocationActivity extends Activity {
  52. private static final int MAX_RECENT_DEST_COUNT = 10;
  53. public static final String PREFS_NAME = "WalkyTalky";
  54. private static final String RECENT_DESTINATIONS_PREFS_KEY = "RECENT_DESTINATIONS";
  55. private static final String FAVORITE_DESTINATIONS_PREFS_KEY = "FAVORITE_DESTINATIONS";
  56. private NewLocationActivity self;
  57. private SharedPreferences prefs;
  58. private ArrayList<String> recentDestinations;
  59. private ArrayList<String> favoriteDestinations;
  60. private HashMap<String, String> contactDestinations;
  61. private AutoCompleteTextView destinationEditText;
  62. private Button goTextInputButton;
  63. private Button goFavoriteButton;
  64. private Button goRecentButton;
  65. private Button goContactButton;
  66. private Button markFavoriteButton;
  67. private Button removeFavoriteButton;
  68. @Override
  69. public void onCreate(Bundle bundle) {
  70. super.onCreate(bundle);
  71. self = this;
  72. prefs = PreferenceManager.getDefaultSharedPreferences(this);
  73. loadContactAddresses();
  74. setContentView(R.layout.new_loc);
  75. destinationEditText = (AutoCompleteTextView) findViewById(R.id.dest_EditText);
  76. destinationEditText.setOnKeyListener(new OnKeyListener() {
  77. public boolean onKey(View v, int keyCode, KeyEvent event) {
  78. // If the event is a key-down event on the "enter" button
  79. if ((event.getAction() == KeyEvent.ACTION_DOWN)
  80. && (keyCode == KeyEvent.KEYCODE_ENTER)) {
  81. // Perform action on key press
  82. String dest = destinationEditText.getText().toString();
  83. if (dest.length() > 0) {
  84. returnToCaller(dest);
  85. }
  86. return true;
  87. }
  88. return false;
  89. }
  90. });
  91. goTextInputButton = (Button) findViewById(R.id.goTextInput_Button);
  92. goTextInputButton.setOnClickListener(new OnClickListener() {
  93. @Override
  94. public void onClick(View v) {
  95. String dest = destinationEditText.getText().toString();
  96. if (dest.length() > 0) {
  97. returnToCaller(dest);
  98. }
  99. }
  100. });
  101. goFavoriteButton = (Button) findViewById(R.id.goFavorite_Button);
  102. goFavoriteButton.setOnClickListener(new OnClickListener() {
  103. @Override
  104. public void onClick(View v) {
  105. goFavoriteHandler();
  106. }
  107. });
  108. goRecentButton = (Button) findViewById(R.id.goRecent_Button);
  109. goRecentButton.setOnClickListener(new OnClickListener() {
  110. @Override
  111. public void onClick(View v) {
  112. goRecentHandler();
  113. }
  114. });
  115. goContactButton = (Button) findViewById(R.id.goContact_Button);
  116. goContactButton.setOnClickListener(new OnClickListener() {
  117. @Override
  118. public void onClick(View v) {
  119. goContactHandler();
  120. }
  121. });
  122. markFavoriteButton = (Button) findViewById(R.id.markFavorite_Button);
  123. markFavoriteButton.setOnClickListener(new OnClickListener() {
  124. @Override
  125. public void onClick(View v) {
  126. markFavoriteHandler();
  127. }
  128. });
  129. removeFavoriteButton = (Button) findViewById(R.id.removeFavorite_Button);
  130. removeFavoriteButton.setOnClickListener(new OnClickListener() {
  131. @Override
  132. public void onClick(View v) {
  133. removeFavoriteHandler();
  134. }
  135. });
  136. }
  137. @Override
  138. public void onResume() {
  139. super.onResume();
  140. recentDestinations = new ArrayList<String>();
  141. String[] savedDests = prefs.getString(RECENT_DESTINATIONS_PREFS_KEY, "").split("\n");
  142. for (int i = 0; i < savedDests.length && !savedDests[0].equals(""); i++) {
  143. recentDestinations.add(savedDests[i]);
  144. }
  145. ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
  146. android.R.layout.simple_dropdown_item_1line, recentDestinations);
  147. destinationEditText.setAdapter(adapter);
  148. favoriteDestinations = new ArrayList<String>();
  149. savedDests = prefs.getString(FAVORITE_DESTINATIONS_PREFS_KEY, "").split("\n");
  150. for (int i = 0; i < savedDests.length && !savedDests[0].equals(""); i++) {
  151. favoriteDestinations.add(savedDests[i]);
  152. }
  153. }
  154. @Override
  155. public boolean onKeyDown(int keyCode, KeyEvent event) {
  156. if (keyCode == KeyEvent.KEYCODE_SEARCH) {
  157. doReco();
  158. return true;
  159. } else if (keyCode == KeyEvent.KEYCODE_BACK) {
  160. // Back button pressed in NewLocationActivity, caller application
  161. // may also exit.
  162. setResult(RESULT_FIRST_USER, getIntent());
  163. finish();
  164. return true;
  165. } else if (keyCode == KeyEvent.KEYCODE_MENU) {
  166. // Open settings
  167. Intent iPrefs = new Intent(this, Settings.class);
  168. iPrefs.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
  169. startActivity(iPrefs);
  170. return true;
  171. } else {
  172. return super.onKeyDown(keyCode, event);
  173. }
  174. }
  175. private void doReco() {
  176. Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
  177. intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
  178. RecognizerIntent.LANGUAGE_MODEL_WEB_SEARCH);
  179. startActivityForResult(intent, 0);
  180. }
  181. @Override
  182. public void onDestroy() {
  183. super.onDestroy();
  184. }
  185. private void addRecentDestination(String dest) {
  186. boolean bumpedDestinationUp = false;
  187. for (int i = 0; i < recentDestinations.size(); i++) {
  188. if (recentDestinations.get(i).equals(dest)) {
  189. recentDestinations.remove(i);
  190. recentDestinations.add(0, dest);
  191. bumpedDestinationUp = true;
  192. break;
  193. }
  194. }
  195. while (recentDestinations.size() > MAX_RECENT_DEST_COUNT) {
  196. recentDestinations.remove(recentDestinations.size() - 1);
  197. }
  198. if (!bumpedDestinationUp) {
  199. recentDestinations.add(0, dest);
  200. }
  201. String savedDests = "";
  202. for (int i = 0; i < recentDestinations.size(); i++) {
  203. savedDests = savedDests + recentDestinations.get(i) + "\n";
  204. }
  205. Editor editor = prefs.edit();
  206. editor.putString(RECENT_DESTINATIONS_PREFS_KEY, savedDests);
  207. editor.commit();
  208. }
  209. private void addFavoriteDestination(String dest) {
  210. favoriteDestinations.add(0, dest);
  211. String savedDests = "";
  212. for (int i = 0; i < favoriteDestinations.size(); i++) {
  213. savedDests = savedDests + favoriteDestinations.get(i) + "\n";
  214. }
  215. Editor editor = prefs.edit();
  216. editor.putString(FAVORITE_DESTINATIONS_PREFS_KEY, savedDests);
  217. editor.commit();
  218. }
  219. private void goFavoriteHandler() {
  220. int favoriteDestinationsSize = favoriteDestinations.size();
  221. if (favoriteDestinationsSize == 0) {
  222. return;
  223. }
  224. AlertDialog.Builder builder = new AlertDialog.Builder(self);
  225. final CharSequence[] items = new CharSequence[favoriteDestinationsSize];
  226. for (int i = 0; i < favoriteDestinationsSize; i++) {
  227. items[i] = favoriteDestinations.get(i);
  228. }
  229. builder.setItems(items, new DialogInterface.OnClickListener() {
  230. @Override
  231. public void onClick(DialogInterface dialog, int which) {
  232. String dest = (String) items[which];
  233. if (dest.length() > 0) {
  234. returnToCaller(dest);
  235. }
  236. }
  237. });
  238. AlertDialog dialog = builder.create();
  239. dialog.getListView().setTextFilterEnabled(true);
  240. dialog.show();
  241. }
  242. private void goRecentHandler() {
  243. int recentDestinationsSize = recentDestinations.size();
  244. if (recentDestinationsSize == 0) {
  245. return;
  246. }
  247. AlertDialog.Builder builder = new AlertDialog.Builder(self);
  248. final CharSequence[] items = new CharSequence[recentDestinationsSize];
  249. for (int i = 0; i < recentDestinationsSize; i++) {
  250. items[i] = recentDestinations.get(i);
  251. }
  252. builder.setItems(items, new DialogInterface.OnClickListener() {
  253. @Override
  254. public void onClick(DialogInterface dialog, int which) {
  255. String dest = (String) items[which];
  256. if (dest.length() > 0) {
  257. returnToCaller(dest);
  258. }
  259. }
  260. });
  261. AlertDialog dialog = builder.create();
  262. dialog.getListView().setTextFilterEnabled(true);
  263. dialog.show();
  264. }
  265. private void markFavoriteHandler() {
  266. int recentDestinationsSize = recentDestinations.size();
  267. if (recentDestinationsSize == 0) {
  268. return;
  269. }
  270. AlertDialog.Builder builder = new AlertDialog.Builder(self);
  271. final CharSequence[] items = new CharSequence[recentDestinationsSize];
  272. for (int i = 0; i < recentDestinationsSize; i++) {
  273. items[i] = recentDestinations.get(i);
  274. }
  275. builder.setItems(items, new DialogInterface.OnClickListener() {
  276. @Override
  277. public void onClick(DialogInterface dialog, int which) {
  278. String dest = (String) items[which];
  279. addFavoriteDestination(dest);
  280. }
  281. });
  282. AlertDialog dialog = builder.create();
  283. dialog.getListView().setTextFilterEnabled(true);
  284. dialog.show();
  285. }
  286. private void removeFavoriteHandler() {
  287. int favoriteDestinationsSize = favoriteDestinations.size();
  288. if (favoriteDestinationsSize == 0) {
  289. return;
  290. }
  291. AlertDialog.Builder builder = new AlertDialog.Builder(self);
  292. final CharSequence[] items = new CharSequence[favoriteDestinationsSize];
  293. for (int i = 0; i < favoriteDestinationsSize; i++) {
  294. items[i] = favoriteDestinations.get(i);
  295. }
  296. builder.setItems(items, new DialogInterface.OnClickListener() {
  297. @Override
  298. public void onClick(DialogInterface dialog, int which) {
  299. favoriteDestinations.remove(which);
  300. String savedDests = "";
  301. for (int i = 0; i < favoriteDestinations.size(); i++) {
  302. savedDests = savedDests + favoriteDestinations.get(i) + "\n";
  303. }
  304. Editor editor = prefs.edit();
  305. editor.putString(FAVORITE_DESTINATIONS_PREFS_KEY, savedDests);
  306. editor.commit();
  307. }
  308. });
  309. AlertDialog dialog = builder.create();
  310. dialog.getListView().setTextFilterEnabled(true);
  311. dialog.show();
  312. }
  313. private void loadContactAddresses() {
  314. contactDestinations = new HashMap<String, String>();
  315. // Get the base URI for People table in Contacts content provider.
  316. // ie. content://contacts/people/
  317. Uri mContacts = StructuredPostal.CONTENT_URI;
  318. // An array specifying which columns to return.
  319. String[] projection = new String[] {
  320. StructuredPostal.DISPLAY_NAME, StructuredPostal.FORMATTED_ADDRESS
  321. };
  322. // Best way to retrieve a query; returns a managed query.
  323. Cursor managedCursor = managedQuery(mContacts, projection, // Which
  324. // columns
  325. // to return.
  326. null, // WHERE clause--we won't specify.
  327. null, // no selection args
  328. Phone.DISPLAY_NAME + " ASC"); // Order-by clause.
  329. boolean moveSucceeded = managedCursor.moveToFirst();
  330. ArrayList<String> contactNames = new ArrayList<String>();
  331. while (moveSucceeded) {
  332. contactDestinations.put(managedCursor.getString(0) + " at "
  333. + managedCursor.getString(1), managedCursor.getString(1));
  334. moveSucceeded = managedCursor.moveToNext();
  335. }
  336. }
  337. private void goContactHandler() {
  338. int contactDestinationsSize = contactDestinations.size();
  339. if (contactDestinationsSize == 0) {
  340. return;
  341. }
  342. AlertDialog.Builder builder = new AlertDialog.Builder(self);
  343. final CharSequence[] items = new CharSequence[contactDestinationsSize];
  344. Iterator<Entry<String, String>> it = contactDestinations.entrySet().iterator();
  345. int i = 0;
  346. while (it.hasNext()) {
  347. Entry<String, String> entry = it.next();
  348. items[i] = entry.getKey();
  349. i++;
  350. }
  351. builder.setItems(items, new DialogInterface.OnClickListener() {
  352. @Override
  353. public void onClick(DialogInterface dialog, int which) {
  354. String dest = contactDestinations.get(items[which]);
  355. if (dest.length() > 0) {
  356. returnToCaller(dest);
  357. }
  358. }
  359. });
  360. AlertDialog dialog = builder.create();
  361. dialog.getListView().setTextFilterEnabled(true);
  362. dialog.show();
  363. }
  364. /**
  365. * Returns (Lat, Lon) pair corresponding to the searched address, to the
  366. * caller Activity.
  367. *
  368. * @param destination Address to search
  369. */
  370. private void returnToCaller(String destination) {
  371. if (destination != null) {
  372. setResult(RESULT_OK, getIntent().putExtra("LOC", destination));
  373. } else {
  374. setResult(RESULT_CANCELED, getIntent());
  375. }
  376. addRecentDestination(destination);
  377. finish();
  378. }
  379. }