title: Geocoder autocomplete in android
body: <p>I've been googling my ass of trying to find someone that are having the same problem as me, without luck. So here's my problem:</p>
  
  <p>I'm trying to implement a autocomplete suggestion of addresses as the user types the name of a place using the geocoder in Android. I want this to behave much the same as the javascript version using a combbox. </p>
  
  <p>I am using a layout with an AutoCompleteTextView, and an arrayadapter to dynamically update the suggestionlist as the user types. I have added a 500ms delay from when the onTextChanged() event is received before a call to the geocoder.getFromLocationName is called using a Handler. If a user types more letter within 500ms, the last event will be cancelled. The problem I am encountering is that the suggestions almost never show up in the UI as selectables in the dropdown. I get the address suggestions, but when I add them to the adapter attached to the autocomplatetextview they simple wont show.</p>
  
  <p>I'm running this on an emulator using API level 7, with google apis included. </p>
  
  <p>Now some source code to aid you:
  The layout:</p>
  
  <pre><code>&lt;LinearLayout android:id="@+id/searchInputLayout"
      android:layout_width="fill_parent"
      android:layout_height="fill_parent"
      android:padding="6dip"
      android:orientation="vertical"&gt;
      &lt;TextView
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:text="@string/searchMessage" /&gt;
      &lt;EditText android:id="@+id/freetextInput" 
          android:hint="@string/searchFreetextLabel"
          android:layout_width="fill_parent" 
          android:layout_height="wrap_content" 
          android:background="@android:drawable/editbox_background" /&gt;
      &lt;CheckBox android:id="@+id/includeVincinityCheckbox"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:text="@string/includeVincinityLabel"
          android:checked="true"
          android:onClick="includeVincinityClick" /&gt;
      &lt;AutoCompleteTextView android:id="@+id/locationInput" 
          android:hint="@string/locationInputHint"
          android:layout_width="fill_parent" 
          android:layout_height="wrap_content" /&gt;
      &lt;Button android:id="@+id/searchButton"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:text="@string/searchBtnLabel" 
          android:onClick="searchBtnClicked" /&gt;
      &lt;/LinearLayout&gt;
  </code></pre>
  
  <p>The source code of my activity (I've omitted code not relevant):</p>
  
  <pre><code>public class SearchLocationTabActivity extends Activity implements TextWatcher, OnItemSelectedListener {
  
  private static final int MESSAGE_TEXT_CHANGED = 0;
  private static final int AUTOCOMPLETE_DELAY = 500;
  private static final int THRESHOLD = 3;
  private String latitude, longitude;
  private List&lt;Address&gt; autoCompleteSuggestionAddresses;
  private ArrayAdapter&lt;String&gt; autoCompleteAdapter;
  private Handler messageHandler;
  
  /** Called when the activity is first created. */
  @Override
  public void onCreate(Bundle icicle) {
      super.onCreate(icicle);
      setContentView(R.layout.search);
      setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL);
  
      messageHandler = new MyMessageHandler(this, this);
      autoCompleteAdapter = new ArrayAdapter&lt;String&gt;(this, android.R.layout.simple_dropdown_item_1line, new ArrayList&lt;String&gt;());
      autoCompleteAdapter.setNotifyOnChange(false);
      AutoCompleteTextView locationinput = (AutoCompleteTextView) findViewById(R.id.locationInput);
      locationinput.addTextChangedListener(this);
      locationinput.setOnItemSelectedListener(this);
      locationinput.setThreshold(THRESHOLD);
      locationinput.setAdapter(autoCompleteAdapter);
  }
  
  @Override
  public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
      messageHandler.removeMessages(MESSAGE_TEXT_CHANGED);
  }
  
  @Override
  public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
  String value = arg0.toString();
  if (!"".equals(value) &amp;&amp; value.length() &gt;= THRESHOLD) {
      Message msg = Message.obtain(messageHandler, MESSAGE_TEXT_CHANGED, arg0.toString());
      messageHandler.sendMessageDelayed(msg, AUTOCOMPLETE_DELAY);
  } else {
      autoCompleteAdapter.clear();
  }
  }
  
  @Override
  public void afterTextChanged(Editable arg0) {
  }
  
  @Override
  public void onItemSelected(AdapterView&lt;?&gt; arg0, View arg1, int arg2, long arg3) {
      if (arg2 &lt; autoCompleteSuggestionAddresses.size()) {
          Address selected = autoCompleteSuggestionAddresses.get(arg2);
          latitude = Double.toString(selected.getLatitude());
          longitude = Double.toString(selected.getLongitude());
      }
  }
  
  private void notifyResult(List&lt;Address&gt; suggestions) {
      latitude = longitude = null;
      autoCompleteAdapter.clear();
      for (Address a : autoCompleteSuggestionAddresses) {
          autoCompleteAdapter.add(a.toString());//TODO: figure out a nice way to display this address in list
      }
      autoCompleteAdapter.notifyDataSetChanged();
  }
  
  @Override
  public void onNothingSelected(AdapterView&lt;?&gt; arg0) {
      latitude = longitude = null;
  }
  
  private class MyMessageHandler extends Handler {
  
      private Context context;
      private AsyncTaskSubscriber subscriber;
  
      public MyMessageHandler(Context context, AsyncTaskSubscriber subscriber) {
          this.context = context;
          this.subscriber = subscriber;
      }
  
      @Override
      public void handleMessage(Message msg) {
          if (msg.what == MESSAGE_TEXT_CHANGED) {
              String enteredText = (String) msg.obj;
  
              try {
                  autoCompleteSuggestionAddresses = new Geocoder(context).getFromLocationName(enteredText, 10);
  
                  notifyResult(response);
              } catch (IOException ex) {
                  Log.e(GeoCoderAsyncTask.class.getName(), "Failed to get autocomplete suggestions", ex);
              }
          }
      }
  }
  }
  </code></pre>
  
  <p>Any help is much appreciated!</p>