Android My Location-Fix

Когда вызывается моя активность карты, я делаю вызов в onCreate для addUserMapPoint. Эта функция содержит два экземпляра, в которых я пытаюсь получить информацию о местоположении, используя myOverlay.getMyLocation. При начальной загрузке этого действия результат первой попытки возвращает нулевой GeoPoint, и после того, как основной поток пользовательского интерфейса завершает вторую попытку, расположенную в потоке прослушивателя myOverlay.runOnFirstFix(new Runnable()… вызывается через секунду и содержит GeoPoint, который содержит широту и долготу. Вызов внутри этой функции прослушивателя, кажется, ставит точку на карте, а строка mapController.animateTo(gp) действительно перемещает карту в мое местоположение. В моем приложении есть кнопка обновления, которая, когда щелчок снова запускает это действие. Мне нужны широта и долгота, чтобы получить данные о местоположении из другой службы. После обновления во второй раз через код активности карты я ожидал, что первый вызов myOverlay.getMyLocation() теперь будет удалось получить GeoPoint, но он по-прежнему равен нулю.

Если я не могу получить GeoPoint этим первым вызовом myOverlay.getMyLocation, то как я могу передать значение широты и долготы из второго вызова, найденного в потоке myOverlay.runOnFirstFix(new Runnable()…). Вы заметите, что Я пытался добавить широту и долготу в MyApp, который является классом вспомогательного компонента, но широта и долгота в этом классе равны нулю даже после обновления.Если я вручную устанавливаю широту и долготу вручную в функции addUserMapPoint в первый раз, когда действие Доступ к этим значениям сохраняется Я предполагаю, что это связано с тем, что он устанавливается в основном потоке пользовательского интерфейса.

public class MapActivity extends com.google.android.maps.MapActivity {
    private MapView mapView = null;
    private MapController mapController = null;
    private MyLocationOverlay myOverlay = null;

    public static MyApp app;

    @Override
    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_map);

        app = (MyApp) getApplicationContext();

        mapView = (MapView) findViewById(R.id.mapview);
        mapView.setBuiltInZoomControls(true);
        mapController = mapView.getController();

        List<Overlay> mapOverlays = mapView.getOverlays();
        mapOverlays.clear();

        addUserMapPoint(mapView);

        if (!app.isLocServOff()) {
            //map other points – service call to get items from our service near lat and lon
            addOtherMapPoints(mapOverlays);

        } else {
            Toast.makeText(app.getApplicationContext(),"Current location could not be found.",Toast.LENGTH_LONG).show();
        }

    }

    private void addUserMapPoint(MapView mapView){
            myOverlay = new MyLocationOverlay(app.getApplicationContext(), mapView);
            myOverlay.disableCompass();
        myOverlay.enableMyLocation();


            if(app.getMyLat()==null||app.getMyLon()==null){
                GeoPoint gp = myOverlay.getMyLocation();
                if(gp!=null){
                    app.setMyLat(Helper.latLon1E6Calc(gp.getLatitudeE6()));
                    app.setMyLon(Helper.latLon1E6Calc(gp.getLongitudeE6()));
                    app.setLocServOff(false);
                }else{
                    app.setLocServOff(true);
                }
        }


        myOverlay.runOnFirstFix(new Runnable() {   
                public void run() {     
                    GeoPoint gp = myOverlay.getMyLocation();    
                    if(gp!=null){
                        app.setMyLat(Helper.latLon1E6Calc(gp.getLatitudeE6()));
                        app.setMyLon(Helper.latLon1E6Calc(gp.getLongitudeE6()));
                        app.setLocServOff(false);   
                        mapController.animateTo(gp);
                    }else{
                        app.setLocServOff(true);
                    }
                }    
            });

        mapView.getOverlays().add(myOverlay);
    }   

}

Ваша помощь требуется для следующего вопроса. Как я могу получить GeoPoint, который содержит широту и долготу в основном потоке пользовательского интерфейса, или как я могу передать эти значения из GeoPoint, которые я могу получить из потока myOverlay.runOnFirstFix(new Runnable()…)?

Если вы собираетесь предложить мне использовать Handler или runOnUiThread, пожалуйста, предоставьте пример кода, который передает широту и долготу обратно чему-то, что может использоваться основным потоком пользовательского интерфейса/представлением карты. Я пробовал такие вещи, как следующий код, который не дал желаемого результата. Мне удалось отобразить всплывающее сообщение, но я не смог передать широту и долготу так, как я мог бы использовать.

    final Handler handler = new Handler();   
    myOverlay.runOnFirstFix(new Runnable() {                     
        @Override public void run() {

            handler.post(new Runnable() {                                   
                @Override public void run() {

                        GeoPoint gp = myOverlay.getMyLocation();    
                        if(gp!=null){
                            app.setMyLat(Helper.latLon1E6Calc(gp.getLatitudeE6()));
                            app.setMyLon(Helper.latLon1E6Calc(gp.getLongitudeE6()));
                            app.setLocServOff(false);   
                            mapController.animateTo(gp);                                

                        }else{
                            app.setLocServOff(true);
                        }

                    //Toast.makeText(getApplicationContext(),"wowoowowowoowoowowow",Toast.LENGTH_LONG).show();                      
                    }                                  
                });

            }                
        }); 

Я также использовал код, подобный следующему, чтобы получить широту и долготу, и он работает, но поскольку текущее местоположение иногда будет отличаться от широты и долготы, чем то, что было возвращено, потому что, например, я не мог получить сигнал GPS, но все же было возвращено старое значение. Я добавил проверки, чтобы увидеть, были ли данные широты/долготы старше 2 минут, но я по-прежнему не мог сопоставить самые последние значения широты и долготы с данными, возвращаемыми myOverlay.getMyLocation.

    LocationManager locMgr = (LocationManager)appcontext.getSystemService(Context.LOCATION_SERVICE);
    MyLocationListener locLstnr = new MyLocationListener();

    //fetch current location for current location 
    locMgr.requestSingleUpdate(LocationManager.GPS_PROVIDER, locLstnr, appcontext.getMainLooper());  

person ItBHarsH    schedule 19.12.2012    source источник


Ответы (5)


handler.post(new Runnable() {                                   
            @Override public void run() {

                    GeoPoint gp = myOverlay.getMyLocation();    
                    if(gp!=null){
                        app.setMyLat(Helper.latLon1E6Calc(gp.getLatitudeE6()));
                        app.setMyLon(Helper.latLon1E6Calc(gp.getLongitudeE6()));
                        app.setLocServOff(false);

                        // HERE WE HAVE VALID gp VALUE AND WE NEED TO SHARE IT

                        mapController.animateTo(gp);                                

                    }else{
                        app.setLocServOff(true);
                    }
                }                                  
            });

Я думаю, что ваш app.set/get|MyLat/Lon не работает, потому что вы вызываете их из разных потоков. Чтобы исправить это, синхронизируйте set и get методы для MyLat/Long. (создать Объект для синхронизации и синхронизировать по нему)

Или, если вам нравится ваш способ с обработчиком, это должно работать:

final Handler handler = new Handler(); // BE SURE TO RUN THIS LINE ON UI THREAD
...   
myOverlay.runOnFirstFix(new Runnable() {                     
    @Override public void run() {

        // THIS PART WORKS AS BEFORE
        final GeoPoint gp = myOverlay.getMyLocation();
        mapController.animateTo(gp);                        
        ...
        // AND THIS RUNNABLE TO UPDATE MyLat/MyLong FROM UI THREAD
        handler.post(new Runnable() {                                   
            @Override public void run() {
               app.setMyLat(Helper.latLon1E6Calc(gp.getLatitudeE6()));
               app.setMyLon(Helper.latLon1E6Calc(gp.getLongitudeE6()));
            });

        }                
    }); 
person Leonidos    schedule 28.12.2012
comment
В то время как все посты других были великолепны и описывали, как использовать GPS для определения местоположения, ваш пост был наиболее прямым ответом на мой вопрос. Я смог использовать «handler.post» и «run()» для заполнения значений широты и долготы в моем классе приложения, которые можно оценить по моей активности на карте после обновления. Я хотел бы увидеть пример выполнения этого с помощью синхронизированных методов установки и получения в моем объекте приложения, если у вас есть время предоставить. Спасибо всем за участие и веселого и безопасного Нового года! - person ItBHarsH; 29.12.2012

Ниже вы можете найти несколько примеров того, как получить текущее местоположение в потоке пользовательского интерфейса, но, прежде всего, некоторую справочную информацию.

GPS может потребоваться некоторое время (от 15 секунд до 1 минуты), чтобы получить первое исправление после запроса нового местоположения. По этой причине ваша первая попытка получить его из myOverlay не удалась, и только после первого исправления вы можете получить значение.

Во время этого периода отключения вы можете использовать getLastKnownLocation(), чтобы получить последнее известное надежное местоположение GPS, если вы спешите. Если он недоступен, он возвращает null

Код:

Последнее известное местоположение

LocationManager locMgr=(LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
Location loc = locMgr.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if(loc != null){
    //we have a valid location. Check location date
}

Запрос обновления одного местоположения

LocationManager locMgr=(LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
locMgr.requestSingleUpdate(LocationManager.GPS_PROVIDER, locationListener, appcontext.getMainLooper);

Запрос непрерывного обновления местоположения

LocationManager locMgr = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
//use 0 for minDistance and minDistance between updates if you need the maximum update frequency.
locMgr.requestLocationUpdates(LocationManager.GPS_PROVIDER, minDistance, minTime, locationListener);

Прослушиватель местоположения для одиночного и непрерывного обновления местоположения

Это последний фрагмент кода, и это место, где вы получаете новые свежие местоположения, запрошенные выше.

Когда новое местоположение, соответствующее вашему критерию запроса, определенному выше, извлекается с помощью GPS, этот прослушиватель немедленно вызывается, если только ваше устройство не занято чем-то другим, что не может быть прервано (например, обратный вызов находится в приостановленном потоке или который попал в блокировку) .

Изнутри onLocationChanged() вы можете установить любой уровень класса по мере необходимости. Если вы зарегистрировали прослушиватель из потока пользовательского интерфейса, то он будет работать в пользовательском интерфейсе.

LocationListener locationListener = new LocationListener() {
    public void onLocationChanged(Location fix) {
        fix.setTime(fix.getTime() + timeZoneOffset); //Add Timezone offset if needed
        //here you have a fresh new location in fix...
        //You can set the value of any class level field from here
    }

    public void onProviderDisabled(String provider) {
    }

    public void onProviderEnabled(String provider) {
    }

    public void onStatusChanged(String provider, int status, Bundle extras) {
    }
};

С Уважением.

person Luis    schedule 22.12.2012

Вот некоторые из наиболее важных моментов, которые необходимо учитывать при поиске местоположения устройства:

  1. Точное время спутниковой GPS-фиксации не гарантируется. Например. устройство находится внутри здания / не под открытым небом.
  2. Убедитесь, что спутниковые приемники GPS не остаются активными в течение длительного времени. Если прослушиватель включен, это означает, что GPS-радио постоянно включено, что является основной причиной разряда батареи.

В приведенном ниже примере кода метод опроса в LinkedBlockingQueue не возвращает значение до тех пор, пока не истечет указанный интервал времени или не будет поставлено в очередь расположение.

Используйте что-то вроде приведенного ниже, чтобы получить текущее местоположение:

    Location getCurrentLocation() {
    long startmillis = 0;
    LinkedBlockingQueue<Location> mQueue = new LinkedBlockingQueue<Location>();
            try{


                long millisSinceLastCollection = System.currentTimeMillis() - startmillis; 


                startmillis = System.currentTimeMillis();
                mQueue.clear();

    // Register for Satellite GPS listener as well as Network GPS listener.
                registerGPSListeners();

                // Wait for a maximum of one minutes for a fix
                Location firstfix = mQueue.poll(1, TimeUnit.MINUTES);


                if(firstfix != null && firstfix.getProvider().equals(LocationManager.GPS_PROVIDER)) {
                    return firstfix;
                }

                long elapsedmillis = System.currentTimeMillis() - startmillis;
                long remainingmillis = ONE_MINUTE_IN_MS - elapsedmillis; 
                if (remainingmillis <= 0){
                    return firstfix;
                }

                Location secondfix = mQueue.poll(remainingmillis, TimeUnit.MILLISECONDS);

                if(secondfix != null && secondfix.getProvider().equals(LocationManager.GPS_PROVIDER)) {
                    return secondfix;
                }

                /*
                 * In case we receive fix only from Network provider, return it.
                 */
                if(firstfix != null && firstfix.getProvider().equals(LocationManager.NETWORK_PROVIDER)) {
                    return firstfix;
                }

            } catch(Exception e){
                Logger.e("GPS: Exception while listening for the current location", e);
            } finally {
                Logger.i("GPS: Unsubscribing from any existing GPS listeners");
                unregisterGPSListeners();

            }
    }


// GPS issue fix edit.
    private void registerGPSListeners() {

        LocationManager locationManager = (LocationManager)AirWatchApp.getAppContext().getSystemService(Context.LOCATION_SERVICE);

        if(locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER))
            locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 30000, 100, oneShotNetworkGPSLocationListener, MyAppApp.getAppContext().getMainLooper());

        if(locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)){
            locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30000, 100, oneShotSatelliteGPSLocationListener, AirWatchApp.getAppContext().getMainLooper());
        }
    }

    private void unregisterGPSListeners(){

        final LocationManager locationManager = (LocationManager)MyApp.getAppContext().getSystemService(Context.LOCATION_SERVICE);
        locationManager.removeUpdates(oneShotSatelliteGPSLocationListener);
        locationManager.removeUpdates(oneShotNetworkGPSLocationListener);
    }

//One shot location listener
    protected LocationListener oneShotSatelliteGPSLocationListener = new LocationListener() {
        public void onLocationChanged(Location location) {

            try {
                mQueue.put(location);
            } catch (InterruptedException e) {
                Logger.e("Exception in putting new Location to the queue", e);
            }

            Logger.d("GPS: Location received from Satellite GPS Provider");
            unregisterGPSListeners();
        }

        public void onProviderDisabled(String provider) {}
        public void onStatusChanged(String provider, int status, Bundle extras) {}
        public void onProviderEnabled(String provider) {}
    };

    //One shot location listener
    protected LocationListener oneShotNetworkGPSLocationListener = new LocationListener() {
        public void onLocationChanged(Location location) {

            try {
                mQueue.put(location);
            } catch (InterruptedException e) {
                Logger.e("Exception in putting new Location to the queue", e);
            }

            Logger.d("GPS: Location received from Network GPS Provider");
            // Stop Listener for one-shot location fix from Network GPS provider.
            final LocationManager locationManager = (LocationManager)AirWatchApp.getAppContext().getSystemService(Context.LOCATION_SERVICE);
            locationManager.removeUpdates(oneShotNetworkGPSLocationListener);
            Logger.d("GPS: Unsubscribed the network location listener.");
        }

        public void onProviderDisabled(String provider) {}
        public void onStatusChanged(String provider, int status, Bundle extras) {}
        public void onProviderEnabled(String provider) {}
    };
person Nitin Sethi    schedule 27.12.2012

Android изменяет пользовательский интерфейс и обрабатывает события ввода из одного потока пользовательского интерфейса (основного потока).

Если программист не использует конструкции параллелизма, весь код Android-приложения выполняется в этом потоке.

GPS — это лучший способ определить местоположение пользователя, но слишком частое пингование спутника глобального позиционирования быстро разряжает батарею мобильного устройства, для определения местоположения пользователя требуется много времени, и этот метод не всегда работает в помещении. You are not getting your location in first attempt that's why you are getting null over there.

Android Network Location Provider определяет местоположение пользователя на основе сигналов сотовой вышки и Wi-Fi. Он не только использует меньше энергии батареи, чем GPS, но также работает быстрее и работает независимо от того, находится ли пользователь снаружи или внутри.

Я даю свой рабочий код ниже, который показывает progress dialog, прослушивает местоположение пользователя и после получения местоположения показывает location overlay пользователя на карте Google

Я предполагаю, что у вас есть следующие разрешения в вашем Menifest file
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.INTERNET"/>
мой основной класс

public class MyLocationOnMap extends MapActivity {

private MapView mapView;
private MyLocationOverlay itemizedoverlay;
private LocationManager locationManager;
private String provider;
private MyLocationListener locationListener;
MyBroadCastreceiver myBroadCastreceiver;
/**
 * My current Location <i>longitude</i>.
 */
static int longitude;
/**
 * My current Location <i>latitude</i>.
 */
static int latitude;
/**
 *My progress indicator. 
 */
ProgressDialog loadingDialog;

public static final String INTENT_FILTER_TAG="my location broadcast receiver";


/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.my_location_on_map);

    loadingDialog = new ProgressDialog(this);
    loadingDialog.setTitle("Hot Spots!");
    loadingDialog.setMessage("Please wait ...");
    loadingDialog.setIndeterminate(true);
    loadingDialog.setCancelable(false);

    loadingDialog.show();

 // Configure the Map
    mapView = (MapView) findViewById(R.id.mapview);
    mapView.setBuiltInZoomControls(true);
    mapView.setStreetView(true);

    /**
     * Get your location manager and Location Listener...
     */
    locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    locationListener=new MyLocationListener();

    myBroadCastreceiver = new MyBroadCastreceiver();

        if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
            Log.i("GPS_Enabled", "GPS enable! listening for gps location.");
            locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 10000, 0, locationListener);
            registerReceiver(myBroadCastreceiver, new IntentFilter(INTENT_FILTER_TAG));
        } else if (locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
            Log.i("Network_Enabled", "Network enable! listening for Network location.");
            locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 10000, 0, locationListener);
            registerReceiver(myBroadCastreceiver, new IntentFilter(INTENT_FILTER_TAG));
        } else {
            loadingDialog.dismiss();
            Toast.makeText(this, "No Provider enable!", Toast.LENGTH_LONG).show();
        }

}//End of onCreate......

 /**
 * My BroadCast Receiver, that is called when i get the location of user.
 * @author Rupesh Yadav.
 *
 */
class MyBroadCastreceiver extends BroadcastReceiver{

    @Override
    public void onReceive(Context context, Intent intent) {
        //Remove location update when you get user`s location very first time.
        locationManager.removeUpdates(locationListener);
        //Remove the broadcast listener that update my location on map.
        unregisterReceiver(myBroadCastreceiver);

        GeoPoint point = new GeoPoint(latitude, longitude);
        mapView.getController().animateTo(point);

        List<Overlay> mapOverlays = mapView.getOverlays();
        Drawable drawable = MyLocationOnMap.this.getResources().getDrawable(R.drawable.hs_mapoverlay);
        itemizedoverlay = new MyLocationOverlay(drawable, MyLocationOnMap.this);

        OverlayItem overlayitem = new OverlayItem(point, "Hello!", "My Current Location :)");

        itemizedoverlay.addOverlay(overlayitem);
        mapOverlays.add(itemizedoverlay);

        loadingDialog.dismiss();

    }

}

/**
 * My Location listener...
 */
class MyLocationListener implements LocationListener{
    @Override
    public void onLocationChanged(Location location) {
        latitude=(int) ((location.getLatitude())*1E6);
        longitude=(int) ((location.getLongitude())*1E6);

        //Send broadcast to update my location.
        Intent sendLocationIntent=new Intent(INTENT_FILTER_TAG);
        sendBroadcast(sendLocationIntent);
    }
    @Override
    public void onProviderDisabled(String provider) {
        // TODO Auto-generated method stub
    }
    @Override
    public void onProviderEnabled(String provider) {
        // TODO Auto-generated method stub
    }
    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {
        // TODO Auto-generated method stub
    }

}

@Override
protected boolean isRouteDisplayed() {
    // TODO Auto-generated method stub
    return false;
}

}

Класс MyLocationOverlay

public class MyLocationOverlay extends ItemizedOverlay<OverlayItem> {

Context mContext;
private ArrayList<OverlayItem> hsOverlays = new ArrayList<OverlayItem>();

public MyLocationOverlay(Drawable defaultMarker) {
    super(boundCenterBottom(defaultMarker));
    // TODO Auto-generated constructor stub
}

public MyLocationOverlay(Drawable defaultMarker, Context context) {
    super(boundCenterBottom(defaultMarker));
    mContext = context;
}

@Override
protected OverlayItem createItem(int i) {
    // TODO Auto-generated method stub
    return hsOverlays.get(i);
}

@Override
public int size() {
    // TODO Auto-generated method stub
    return hsOverlays.size();
}

/**
 * add new OverlayItem objects to map OverlayItem ArrayList.
 * 
 * @param overlay
 */
public void addOverlay(OverlayItem overlay) {
    hsOverlays.add(overlay);
    populate();
}

/**
 * Called when user clicks on map overlay.
 */
@Override
protected boolean onTap(int index) {
    // TODO Auto-generated method stub
    // return super.onTap(index);
    OverlayItem item = hsOverlays.get(index);
    AlertDialog.Builder dialog = new AlertDialog.Builder(mContext);
    dialog.setTitle(item.getTitle());
    dialog.setMessage(item.getSnippet());
    dialog.show();
    return true;
}

Вы можете изменить Location Listener и Broadcasr Receiver в соответствии с вашими потребностями. Надеюсь, это решит вашу проблему.
С уважением!

person Rupesh Yadav    schedule 28.12.2012

Я использовал этот класс для определения широты и долготы: надеюсь, это будет полезно и для вас.

Пример использования: GPSUtility.getInstance(Context).getLatitude(); GPSUtility.getInstance(CamPhotoModeAct.this).getLongitude()

public class GPSUtility {
    public static final String TAG = "GPSUtility";

    private Context ctx;

    Timer timer1;
    LocationManager lm;
    LocationResult locationResult;
    boolean gps_enabled=false;
    boolean network_enabled=false;

    private double latitude;
    private double longitude;

    private static SharedPreferences SHARED_PREF;
    private static SharedPreferences.Editor EDITOR_SHARED_PREF;

    private static GPSUtility this_instance;

    public GPSUtility(Context ctx){
        this.ctx = ctx;
        SHARED_PREF = ctx.getSharedPreferences(ConstantsG.SHARED_PREF_FILE, Context.MODE_PRIVATE);
        EDITOR_SHARED_PREF = SHARED_PREF.edit();
        this.getLocation(innerLocationResult);
    }

    public static GPSUtility getInstance(Context ctx){
        if(this_instance == null)
            this_instance = new GPSUtility(ctx);
        return this_instance;
    }

    public static void updateLocation(Context ctx){
        GPSUtility.getInstance(ctx);//this writes the latitude and longitude in sharable preference file
    }

    public double getLatitude(){
        String latitudeStr = SHARED_PREF.getString(ConstantsG.KEY_LATITUDE,null);
        if(latitudeStr == null){
            latitude = 0.0;
        }
        else{
            latitude = Double.parseDouble(latitudeStr);
        }
        return latitude;
    }

    public double getLongitude(){
        String longitudeStr = SHARED_PREF.getString(ConstantsG.KEY_LONGITUDE,null);
        if(longitudeStr == null){
            longitude = 0.0;
        }
        else{
            longitude = Double.parseDouble(longitudeStr);
        }
        return longitude;
    }

    private void updateWithNewLocation(Location location) {

        if (location != null) {
            latitude = location.getLatitude();
            EDITOR_SHARED_PREF.putString(ConstantsG.KEY_LATITUDE, String.valueOf(latitude) );

            longitude = location.getLongitude();
            EDITOR_SHARED_PREF.putString(ConstantsG.KEY_LONGITUDE, String.valueOf(longitude));

            EDITOR_SHARED_PREF.commit();
        }
    }

    public boolean getLocation(LocationResult result)
    {
        //I use LocationResult callback class to pass location value from GPSUtility to user code.
        locationResult=result;
        if(lm==null)
            lm = (LocationManager) this.ctx.getSystemService(Context.LOCATION_SERVICE);

        //exceptions will be thrown if provider is not permitted.
        try {
            gps_enabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
        } catch (Exception ex) {
            Log.e(TAG, "Exception error: " + ex.getLocalizedMessage(), ex);
        }
        try {
            network_enabled = lm
                    .isProviderEnabled(LocationManager.NETWORK_PROVIDER);
        } catch (Exception ex) {
            Log.e(TAG, "Exception error: " + ex.getLocalizedMessage(), ex);
        }

        //Toast.makeText(context, gps_enabled+" "+network_enabled,     Toast.LENGTH_LONG).show();

        //don't start listeners if no provider is enabled
        if(!gps_enabled && !network_enabled){
            Toast.makeText(this.ctx, "You should enable gps or be connected to network.", Toast.LENGTH_LONG).show();
            return false;
        }

        if(gps_enabled)
            lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListenerGps);
        if(network_enabled)
            lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListenerNetwork);
        timer1=new Timer();


        timer1.schedule(new GetLastLocation(), 10000);
        return true;
    }

    LocationListener locationListenerGps = new LocationListener() {
        public void onLocationChanged(Location location) {
            timer1.cancel();
            locationResult.gotLocation(location);
            lm.removeUpdates(this);
            lm.removeUpdates(locationListenerNetwork);
        }
        public void onProviderDisabled(String provider) {}
        public void onProviderEnabled(String provider) {}
        public void onStatusChanged(String provider, int status, Bundle extras) {}
    };

    LocationListener locationListenerNetwork = new LocationListener() {
        public void onLocationChanged(Location location) {
            timer1.cancel();
            locationResult.gotLocation(location);
            lm.removeUpdates(this);
            lm.removeUpdates(locationListenerGps);
        }
        public void onProviderDisabled(String provider) {}
        public void onProviderEnabled(String provider) {}
        public void onStatusChanged(String provider, int status, Bundle extras) {}
    };

    class GetLastLocation extends TimerTask {
        @Override
        public void run() {
            //Context context = getClass().getgetApplicationContext();
             Location net_loc=null, gps_loc=null;
             if(gps_enabled)
                 gps_loc=lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
             if(network_enabled)
                 net_loc=lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);

             //if there are both values use the latest one
             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);
    }

    LocationResult innerLocationResult = new LocationResult() {
        @Override
        public void gotLocation(Location location) {
            updateWithNewLocation(location);
        }
    };
}
person gezimi005    schedule 28.12.2012