2012-05-15 5 views
1

В попытке получить простой адрес на андроиде, используя геокодер, я попытался проявить терпение и, наконец, решил обратиться за помощью.Адрес автозаполнения на андроиде с использованием геокодера

оригинальный код ссылки: Geocoder autocomplete in android

Таким образом, в приведенном ниже коде, все, что происходит пытается автоматического завершения адреса в качестве пользовательских типов в AutoCompleteTextView. Я вызываю функцию, выполняющую фактическую работу в runOnUiThread, надеясь, что пользовательский интерфейс не будет зависеть, поскольку пользователь вводит код. Однако пользовательский интерфейс зависает после Threshold (3 символа) и выпадающего из возможных адресов появляется у него собственный темп и не всегда.

Если вы, ребята, можете сказать мне, где я неправильно .... спасибо заранее

import java.io.IOException; 
import java.util.ArrayList; 
import java.util.List; 

import android.app.Activity; 
import android.location.Address; 
import android.location.Geocoder; 
import android.os.Bundle; 
import android.os.Handler; 
import android.text.Editable; 
import android.text.TextWatcher; 
import android.util.Log; 
import android.view.View; 
import android.widget.AdapterView; 
import android.widget.AdapterView.OnItemSelectedListener; 
import android.widget.ArrayAdapter; 
import android.widget.AutoCompleteTextView; 

public class AlarmActivity extends Activity implements TextWatcher { 
private static final int THRESHOLD = 3; 
private String latitude, longitude; 
private List<Address> autoCompleteSuggestionAddresses; 
private ArrayAdapter<String> autoCompleteAdapter; 



/** Called when the activity is first created. */ 
@Override 
public void onCreate(Bundle icicle) { 
    super.onCreate(icicle); 
    setContentView(R.layout.hw); 
    setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL); 
    autoCompleteAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_dropdown_item_1line, new ArrayList<String>()); 
    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) { 

} 

@Override 
public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) { 
final String value = arg0.toString(); 

if (!"".equals(value) && value.length() >= THRESHOLD) { 

    Thread t = new Thread() { 
     public void run() { 
      try { 

       runOnUiThread(new Runnable() { 
        public void run() { 
         notifyResult(value); 
        } 
       }); 
      } catch (Exception e) {} 
     } 
    }; 
    t.start(); 


} else { 
    autoCompleteAdapter.clear(); 
} 
} 

@Override 
public void afterTextChanged(Editable arg0) { 
} 


private void notifyResult(String value) { 
    try { 
      autoCompleteSuggestionAddresses = new Geocoder(getBaseContext()).getFromLocationName(value, 10); 

      //notifyResult(autoCompleteSuggestionAddresses); 

      latitude = longitude = null; 
      autoCompleteAdapter.clear(); 
      for (Address a : autoCompleteSuggestionAddresses) { 
       Log.v("Nohsib", a.toString()); 
       String temp = ""+ a.getFeatureName()+" "+a.getCountryName()+" "+a.getPostalCode(); 

       autoCompleteAdapter.add(temp); 
      } 
      autoCompleteAdapter.notifyDataSetChanged(); 



     } catch (IOException ex) { 
      // Log.e(GeoCoderAsyncTask.class.getName(), "Failed to get autocomplete suggestions", ex); 
     } 

} 

}

ответ

0

Я считаю, что причина, по которой пользовательский интерфейс замерзает, потому что даже если вы звоните notifyResult из отдельного потока он все еще запускается в потоке пользовательского интерфейса. Что будет исправить это вместо того, чтобы использовать AsyncTask

Что-то вроде:

private class GetSuggestions extends AsyncTask<String, Void, Void> { 
    protected Long doInBackground(String... search) { 
     value = search[0]; 
     try { 
     autoCompleteSuggestionAddresses = new Geocoder(getBaseContext()).getFromLocationName(value, 10); 

     //notifyResult(autoCompleteSuggestionAddresses); 

     latitude = longitude = null; 
     autoCompleteAdapter.clear(); 
     for (Address a : autoCompleteSuggestionAddresses) { 
      Log.v("Nohsib", a.toString()); 
      String temp = ""+ a.getFeatureName()+" "+a.getCountryName()+" "+a.getPostalCode(); 

      autoCompleteAdapter.add(temp); 
     } 

    } catch (IOException ex) { 
     // Log.e(GeoCoderAsyncTask.class.getName(), "Failed to get autocomplete suggestions", ex); 
    } 
    } 

    protected void onPostExecute(Long result) { 
     autoCompleteAdapter.notifyDataSetChanged(); 
    } 
} 

, а затем вы можете запустить задачу, вызвав новые GetSuggestions() выполнить (значение);.

+1

@ Michaeldcooney: Спасибо за ответ. Однако я пробовал этот подход, и он дает исключение, отредактированное в вашем решении. Поэтому я попробовал называть autoCompleteAdapter.notifyDataSetChanged() с помощью runOnUiThread, но это не дает рекомендаций вообще опускаться. Все предложения? – Nohsib

+0

, если исключение не видно выше: вызвано: android.view.ViewRoot $ CalledFromWrongThreadException: только исходный поток, создавший иерархию представлений, может коснуться его представлений. – Nohsib

+0

Вы получаете эту ошибку, когда в методе onPostExecute? – Michaeldcooney

Смежные вопросы