1

Я пытаюсь получить геоопределение пользователя при запуске приложения, то есть во время заставки.Получение географического местоположения пользователя во время splashscreen

Мой подход заключается в том, чтобы получить местоположение Geo из отдельного класса с использованием asynctask в основном действии. Я новичок в андроиде, поэтому я могу что-то упустить. Вот пример кода, который я написал, чтобы принести гео местоположение пользователя:

SplashScreenActivity.java (извлечение гео расположение без намерения службы)

package work.office; 

import work.office.GeoLocationFinder.LocationResult; 
import android.app.Activity; 
import android.app.ProgressDialog; 
import android.content.Context; 
import android.content.Intent; 
import android.location.Location; 
import android.os.AsyncTask; 
import android.os.Bundle; 
import android.os.Handler; 
import android.util.Log; 
import android.view.Menu; 

public class SplashScreenActivity extends Activity { 

    private static final String TAG = "SplashScreenActivity"; 
    private ProgressDialog pd = null; 
    private Object data = null; 
    LocationResult locationResult; 
    Location newLocation = null; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_splash_screen); 

     new GetGeoLocationAsyncTask(getApplicationContext()).execute(); 
    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     // Inflate the menu; this adds items to the action bar if it is present. 
     getMenuInflater().inflate(R.menu.splash_screen, menu); 
     return true; 
    } 

    private class GetGeoLocationAsyncTask extends 
      AsyncTask<Void, Integer, Location> { 

     private static final String TAG = "GetGeoLocationAsyncTask"; 
     private Context ctx = null; 

     public GetGeoLocationAsyncTask(Context applicationContext) { 
      this.ctx = applicationContext; 
     } 

     @Override 
     protected void onPreExecute() { 
      pd = new ProgressDialog(SplashScreenActivity.this); 
      pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); 
      pd.setTitle("Loading..."); 
      pd.setMessage("Finding your geo location... Please wait"); 
      pd.setCancelable(Boolean.FALSE); 
      pd.setIndeterminate(Boolean.TRUE); 
      pd.setMax(100); 
      pd.setProgress(0); 
      pd.show(); 
      super.onPreExecute(); 
     } 

     @Override 
     protected Location doInBackground(Void... params) { 

        LocationResult locationResult = new LocationResult() { 

         @Override 
         public void gotLocation(Location location) { 
          if (location != null) { 

           newLocation = new Location(location); 
           newLocation.set(location); 
          } else { 
           Log.d(TAG, "Location received is null"); 
          } 

         } 

        }; 
        GeoLocationFinder geoLocationFinder = new GeoLocationFinder(); 
        geoLocationFinder.getLocation(this.ctx, 
          locationResult); 

      return newLocation; 
     } 

     @Override 
     protected void onPostExecute(Location result) { 
      super.onPostExecute(result); 
      if (result != null) { 
       Log.d(TAG, 
         "Got coordinates, congratulations. Longitude = " 
           + result.getLongitude() + " Latitude = " 
           + result.getLatitude()); 
      } else { 
       Log.d(TAG, "Coordinates are null :("); 
      } 
      pd.dismiss(); 
     } 

    } 

} 

GeoLocationFinder.java

package work.office; 

import java.util.Timer; 
import java.util.TimerTask; 

import android.content.Context; 
import android.location.Location; 
import android.location.LocationListener; 
import android.location.LocationManager; 
import android.os.Bundle; 
import android.util.Log; 

public class GeoLocationFinder { 
    private static final String TAG = "GeoLocationFinder"; 
    Timer locationTimer; 
    LocationManager locationManager; 
    Location location; 
    private static final int min_update_time = 20000; // in msec 
    private static final int min_distance_for_update = 10; // in meters 
    LocationResult locationResult; 
    boolean gps_enabled = Boolean.FALSE; 
    boolean network_enabled = Boolean.FALSE; 

    public boolean getLocation(Context ctx, LocationResult result) { 
     locationResult = result; 

     if (locationManager == null) { 
      locationManager = (LocationManager) ctx 
        .getSystemService(Context.LOCATION_SERVICE); 
     } 

     try { 
      gps_enabled = locationManager 
        .isProviderEnabled(LocationManager.GPS_PROVIDER); 
     } catch (Exception e) { 
      Log.d(TAG, "GPS enabled exception: " + e.getMessage()); 
     } 

     try { 
      network_enabled = locationManager 
        .isProviderEnabled(LocationManager.NETWORK_PROVIDER); 
     } catch (Exception e) { 
      Log.d(TAG, "Network enabled exception: " + e.getMessage()); 
     } 

     if (!gps_enabled && !network_enabled) { 
      Log.d(TAG, "You are doomed boy!!"); 
      return Boolean.FALSE; 
     } 

     if (gps_enabled) { 
      locationManager.requestLocationUpdates(
        LocationManager.GPS_PROVIDER, min_update_time, 
        min_distance_for_update, locationListenerGps); 
     } 

     if (network_enabled) { 
      locationManager.requestLocationUpdates(
        LocationManager.NETWORK_PROVIDER, min_update_time, 
        min_distance_for_update, locationListenerNetwork); 
     } 

     locationTimer = new Timer(); 
     locationTimer.schedule(new GetLastLocation(), 20000); 
     return Boolean.TRUE; 
    } 

    LocationListener locationListenerGps = new LocationListener() { 
     public void onLocationChanged(Location location) { 
      locationTimer.cancel(); 
      locationResult.gotLocation(location); 
      locationManager.removeUpdates(this); 
      locationManager.removeUpdates(locationListenerGps); 
     } 

     @Override 
     public void onProviderDisabled(String provider) { 
      Log.d(TAG, "GPS provider disabled" + provider); 

     } 

     @Override 
     public void onProviderEnabled(String provider) { 
      Log.d(TAG, "GPS provider enabled" + provider); 

     } 

     @Override 
     public void onStatusChanged(String provider, int status, Bundle extras) { 
      Log.d(TAG, "GPS status changed"); 

     } 


    }; 

    LocationListener locationListenerNetwork = new LocationListener() { 
     public void onLocationChanged(Location location) { 
      locationTimer.cancel(); 
      locationResult.gotLocation(location); 
      locationManager.removeUpdates(this); 
      locationManager.removeUpdates(locationListenerNetwork); 
     } 

     @Override 
     public void onProviderDisabled(String provider) { 
      Log.d(TAG, "Network provider disabled. " + provider); 

     } 

     @Override 
     public void onProviderEnabled(String provider) { 
      Log.d(TAG, "Network provider enabled. " + provider); 

     } 

     @Override 
     public void onStatusChanged(String provider, int status, Bundle extras) { 
      Log.d(TAG, "Network status changed."); 

     } 
    }; 

    private class GetLastLocation extends TimerTask { 

     @Override 
     public void run() { 
      locationManager.removeUpdates(locationListenerGps); 
      locationManager.removeUpdates(locationListenerNetwork); 
      Location net_loc = null, gps_loc = null; 
      if (gps_enabled) { 
       gps_loc = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); 
      } 
      if (network_enabled) { 
       net_loc = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); 
      } 
      if (gps_loc != null && net_loc != null) { 
       if (gps_loc.getTime() > net_loc.getTime()) { 
        locationResult.gotLocation(gps_loc); 
       } else { 
        locationResult.gotLocation(net_loc); 
       } 
       return; 
      } 

      if (gps_loc != null) { 
       locationResult.gotLocation(gps_loc); 
       return; 
      } 

      if (net_loc != null) { 
       locationResult.gotLocation(net_loc); 
       return; 
      } 

      locationResult.gotLocation(null); 

     } 

    } 

    public static abstract class LocationResult { 
     public abstract void gotLocation(Location location); 
    } 
} 

Когда я устанавливаю этот apk на свой телефон, я получаю эту ошибку: вызвано: java.lang.RuntimeException: не удается создать обработчик внутри потока, который не вызвал Looper .prepare() (в SplashScreenActivity.java, когда в фоновом потоке я пытаюсь получить местоположение)

This question также упоминает об ошибке, но в моем контексте я не могу ее связать. Может быть, потому, что я использовал контекст SplashScreenActivity в фоновом потоке. Но как исправить это? Кроме того, что может быть лучшим подходом к поиску геопозиции во время заставки? Пожалуйста помоги.

ответ

3

Вы серьезно переусердствовали. В этом случае AsyncTask ничего не выполняет. Вот код, упрощенный, но все еще асинхронно получающий местоположение:

package work.office; 
import android.app.Activity; 
import android.app.ProgressDialog; 
import android.content.Context; 
import android.content.Intent; 
import android.location.Location; 
import android.os.AsyncTask; 
import android.os.Bundle; 
import android.os.Handler; 
import android.util.Log; 
import android.view.Menu; 

public class SplashScreenActivity extends Activity { 

    private static final String TAG = "SplashScreenActivity"; 
    private ProgressDialog pd = null; 
    private Object data = null; 
    GeoLocationFinder.LocationResult locationResult; 
    Location newLocation = null; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_splash_screen); 

     setupLocation(); 
    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     // Inflate the menu; this adds items to the action bar if it is present. 
     getMenuInflater().inflate(R.menu.splash_screen, menu); 
     return true; 
    } 

    private void setupLocation() { 
     pd = new ProgressDialog(SplashScreenActivity.this); 
     pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); 
     pd.setTitle("Loading..."); 
     pd.setMessage("Finding your geo location... Please wait"); 
     pd.setCancelable(Boolean.FALSE); 
     pd.setIndeterminate(Boolean.TRUE); 
     pd.setMax(100); 
     pd.setProgress(0); 
     pd.show(); 

     GeoLocationFinder.LocationResult locationResult = new GeoLocationFinder.LocationResult() { 

      @Override 
      public void gotLocation(Location location) { 
       if (location != null) { 

        newLocation = new Location(location); 
        newLocation.set(location); 

        Log.d(TAG, 
          "Got coordinates, congratulations. Longitude = " 
            + newLocation.getLongitude() + " Latitude = " 
            + newLocation.getLatitude()); 
        pd.dismiss(); 
       } else { 
        Log.d(TAG, "Location received is null"); 
       } 

      } 

     }; 
     GeoLocationFinder geoLocationFinder = new GeoLocationFinder(); 
     geoLocationFinder.getLocation(this, 
       locationResult); 
    } 
} 
+0

Я еще не пробовал этот подход. Но из любопытства я использую сеть также как один из провайдеров. Поэтому, если человек не включил свой GPS, но подключен к wi-fi, в этом случае основной поток активности будет вызывать сетевую операцию, которая теперь не разрешена (приложение будет разбиваться с разумом Network on main Activity нить). Для этой цели я написал asynctask. –

+0

Обычно вы устанавливаете LocationListener с помощью метода LocationManager.requestLocationUpdates(). Он будет асинхронным обновлением местоположения. – mach

+0

Я пробовал это. Это сработало. Спасибо за вашу помощь. –

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