Hello, I have never encountered AsyncTask before, and now it's time. I need, in AsyncTask shove location determination. I do this:

protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Geolocation(); } private void Geolocation() { final ProgressDialog progressDialog = new ProgressDialog(this); new AsyncTask<Void, Integer, Void>() { private Exception m_error = null;@Override protected void onPreExecute() { progressDialog.setMessage("Search ..."); progressDialog.setCancelable(false); progressDialog.setMax(100); progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); progressDialog.show(); } protected void doInBackground() { //-------------------------ΠœΠ΅ΡΡ‚ΠΎΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅---------------------------// LocationManager locationManager; String context = Context.LOCATION_SERVICE; locationManager = (LocationManager) getSystemService(context); Criteria criteria = new Criteria(); criteria.setAccuracy(Criteria.ACCURACY_FINE); criteria.setAltitudeRequired(false); criteria.setBearingRequired(false); criteria.setCostAllowed(true); criteria.setPowerRequirement(Criteria.POWER_LOW); String provider = locationManager.getBestProvider(criteria, true); Location location = locationManager.getLastKnownLocation(provider); updateWithNewLocation(location); locationManager.requestLocationUpdates(provider, 2000, 10, locationListener); } // обновляСм progressDialog protected void onProgressUpdate(Integer... values) { progressDialog.setProgress((int)((values[0] / (float) values[1]) * 100)); }; protected void onPostExecute() { // ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°Π΅ΠΌ сообщСниС, Ссли Π²ΠΎΠ·Π½ΠΈΠΊΠ»Π° ошибка if (m_error != null) { m_error.printStackTrace(); return; } // Π·Π°ΠΊΡ€Ρ‹Π²Π°Π΅ΠΌ прогрСсс ΠΈ удаляСм Π²Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹ΠΉ Ρ„Π°ΠΉΠ» progressDialog.hide(); } @Override protected Void doInBackground(Void... params) { // TODO Auto-generated method stub return null; } }; } 

But for some reason it does not work. Tell me please. Although if I remove AsyncTask and insert the code between the "location" comments in OnCreate, then everything will work, but I need it to work in AsyncTask.

UPDATED:

  protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); LocationManager locationManager; String context = Context.LOCATION_SERVICE; locationManager = (LocationManager)getSystemService(context); Criteria criteria = new Criteria(); criteria.setAccuracy(Criteria.ACCURACY_FINE); criteria.setAltitudeRequired(false); criteria.setBearingRequired(false); criteria.setCostAllowed(true); criteria.setPowerRequirement(Criteria.POWER_LOW); String provider = locationManager.getBestProvider(criteria, true); Location location = locationManager.getLastKnownLocation(provider); updateWithNewLocation(location); locationManager.requestLocationUpdates(provider, 2000, 10, locationListener); } private final LocationListener locationListener = new LocationListener() { public void onLocationChanged(Location location) {//постоянноС ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅. updateWithNewLocation(location); } public void onProviderDisabled(String provider){ updateWithNewLocation(null); } public void onProviderEnabled(String provider){ } public void onStatusChanged(String provider, int status, Bundle extras){ } }; @SuppressLint("NewApi") private void updateWithNewLocation(Location location) { String latLongString; TextView myLocationText; myLocationText = (TextView)findViewById(R.id.location); String addressString = "No address found"; if (location != null) { double latitude = location.getLatitude(); double longitude = location.getLongitude(); Geocoder gc = new Geocoder(this, Locale.getDefault()); try { List<Address> addresses = gc.getFromLocation(latitude, longitude, 1); if (addresses.size() > 0) { Address address = addresses.get(0); if (address.getCountryName() != null) { country_location = address.getCountryName(); } if (address.getLocality() != null) { city_location = address.getLocality(); } if (address.getThoroughfare() != null) { street_location = address.getThoroughfare(); } if (address.getFeatureName() != null) { house_location = address.getFeatureName(); } geolocation.append(country_location).append(","); geolocation.append(city_location).append(","); geolocation.append(street_location).append(","); geolocation.append(house_location).append("."); } addressString = geolocation.toString(); } catch (IOException e) {} } else { latLongString = "No location found"; updateWithNewLocation(location); } myLocationText.setText(addressString); } 

UPDATED 2:

  protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.create_consumption); //-------------------------ΠœΠ΅ΡΡ‚ΠΎΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅---------------------------// LocationManager locationManager; String context = Context.LOCATION_SERVICE; locationManager = (LocationManager)getSystemService(context); Criteria criteria = new Criteria(); criteria.setAccuracy(Criteria.ACCURACY_FINE); criteria.setAltitudeRequired(false); criteria.setBearingRequired(false); criteria.setCostAllowed(true); criteria.setPowerRequirement(Criteria.POWER_LOW); String provider = locationManager.getBestProvider(criteria, true); // Location location = locationManager.getLastKnownLocation(provider); Location location; // updateWithNewLocation(location); locationManager.requestLocationUpdates(provider, 2000, 10, locationListener); //-------------------------ΠœΠ΅ΡΡ‚ΠΎΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅---------------------------// mt = new MyTask(); mt.execute(); } private final LocationListener locationListener = new LocationListener() { public void onLocationChanged(Location location) { // updateWithNewLocation(location); } public void onProviderDisabled(String provider){ updateWithNewLocation(null); } public void onProviderEnabled(String provider){ } public void onStatusChanged(String provider, int status, Bundle extras){ } }; @SuppressLint("NewApi") private void updateWithNewLocation(Location location) { String latLongString; TextView myLocationText; myLocationText = (TextView)findViewById(R.id.location); String addressString = "No address found"; if (location != null) { double latitude = location.getLatitude(); double longitude = location.getLongitude(); Geocoder gc = new Geocoder(this, Locale.getDefault()); try { List<Address> addresses = gc.getFromLocation(latitude, longitude, 1); if (addresses.size() > 0) { Address address = addresses.get(0); if (address.getCountryName() != null) { country_location = address.getCountryName(); } if (address.getLocality() != null) { city_location = address.getLocality(); } if (address.getThoroughfare() != null) { street_location = address.getThoroughfare(); } if (address.getFeatureName() != null) { house_location = address.getFeatureName(); } geolocation.append(country_location).append(","); geolocation.append(city_location).append(","); geolocation.append(street_location).append(","); geolocation.append(house_location).append("."); } addressString = geolocation.toString(); } catch (IOException e) {} } else { latLongString = "No location found"; updateWithNewLocation(location); } myLocationText.setText(addressString); } class MyTask extends AsyncTask<Void, Void, Void> { protected void onPreExecute() { super.onPreExecute(); } protected Void doInBackground(Void... params) { updateWithNewLocation(location); return null; } @Override protected void onPostExecute(Void result) { super.onPostExecute(result); } } 

UPDATED:

  private void updateWithNewLocation(Location location) { String latLongString; myLocationText = (TextView)findViewById(R.id.location); String addressString = "No address found"; if (location != null) { double latitude = location.getLatitude(); double longitude = location.getLongitude(); mt = new MyTask(); mt.execute(latitude,longitude); } } class MyTask extends AsyncTask<Double, Void, String> { @Override protected void onPreExecute() { super.onPreExecute(); } protected String doInBackground(Double... params) { String addressString = "No address found"; Geocoder gc = new Geocoder(this, Locale.getDefault()); try { List<Address> addresses = gc.getFromLocation(latitude, longitude, 1); StringBuilder sb = new StringBuilder(); if (addresses.size() > 0) { Address address = addresses.get(0); if (address.getCountryName() != null) { country_location = address.getCountryName(); geolocation.append(country_location).append(","); } if (address.getLocality() != null) { city_location = address.getLocality(); geolocation.append(city_location).append(","); } if (address.getThoroughfare() != null) { street_location = address.getThoroughfare(); geolocation.append(street_location).append(","); } if (address.getFeatureName() != null) { house_location = address.getFeatureName(); geolocation.append(house_location).append("."); } addressString = geolocation.toString(); } return addressString; } } protected void onPostExecute(String addressString) { myLocationText.setText(addressString); } } 
  • one
    Emmm, do the normal code formatting. Otherwise, nothing to understand. And besides, the AsyncTask created must also be called: new MyTask (). Execute (params). In the code I did not see this. In general - the determination of the location to make in task - a dubious undertaking. - DroidAlex
  • I made the formatting, the location determination, I rendered it to the task, because if it is not taken out, the Activity will open for a long time (i.e. until the location is found), and so Activity will open and the user can do something, and the location parallel to be determined. - Serjuk Sep.
  • one
    AsyncTask is designed to perform tasks in the background. In your case, I don’t see something of an ekekuta task. - Salivan
  • Updated code: Activity now opens and hangs. This may be due to the fact that the call updateWithNewLocation (location); and LocationListener are outside the AsyncTask class? and how to do it right? - Serjuk
  • Getting coordinates and so asynchronous, why do you need AsyncTask? Catch your location in locationListener and that's it. - Yura Ivanov


2 answers 2

@Serjuk , A little bit wrong. In the updateWithNewLocation function, you need to start AsyncTask for GeoCoder, i.e. all code that relates to a request to the network and its post-processing should be in another thread.

  1. Received coordinates in locationListener
  2. Run updateWithNewLocation, get latitude and longitude.
  3. Reach the call to the geocoder, launch your AsyncTask<Double, Void, String> (the first parameter is an array of Double width and longitude, the second parameter is progress, not needed, the third parameter is the result, the string returned by the geocoder), passing the latitude and longitude
  4. In doInBackground, make a request to the geocoder, return a string with the geocoder's answer.
  5. In onPostExecute, you are already in the main thread, where you can change the interface and you have the answer to the geocoder.

Look for examples of working with AsyncTask, nothing complicated. Just need to understand at what point where you are (in which stream). And look at the profiler - Pts is a useful thing, though it slows down godlessly ...

  • Please see the latest update. I tried to make an example. I understand that in the execute I pass mt.execute (latitude, longitude); and then in doInBackground I return the string addressString and type it in onPostExecute. But for some reason, I swear at the lines Geocoder gc = new Geocoder (this, Locale.getDefault ()); List <Address> addresses = gc.getFromLocation (latitude, longitude, 1); and on} after return addressString; - Serjuk
  • Try this: doInBackground (Double ... params) {double latitude = params [0]; double longitude = params [1]; Geocoder gc = new Geocoder (YourActivityClass.this, Locale.getDefault ()); List <Address> addresses = gc.getFromLocation (latitude, longitude, 1); ... Syntax errors are difficult to see here, the markup has moved out, check the brackets are superfluous / not enough ... - Yura Ivanov

There are a few comments.

1) It is impossible to display "long-lived" initialization in the constructor. There is the concept of Lazy Initiliazation - in Android it is

2) AsyncTask is essentially a separate thread (thread) of execution. It must first be declared, and then separately run. In this case, you need to do this:

  • Make it in the constructor of Lazy Init (initialization of class members that do not require resources / time)
  • Declare AsyncTask (you have it declared, but anonymously).
  • Next, run your AsyncTask (probably somewhere in onCreate() )

And more advice, try first to avoid anonymous class declarations / methods. This is a great cloud of understanding. Then when you pick up you will use anonymous classes / methods.

  • Yura Ivanov, See if I understood correctly? those. you need the entire updateWithNewLocation (location) function; in AsyncTask to shove? Eclipse swears in protected Void doInBackground (Void ... params) {per line updateWithNewLocation (location); - Serjuk