package com.example.geolocation;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.location.LocationProvider;
import android.os.Bundle;
import org.alfonz.utility.Logcat;
import java.lang.ref.WeakReference;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
public class Geolocation implements LocationListener
{
private static final int LOCATION_AGE = 60000 * 30; // milliseconds
private static final int LOCATION_TIMEOUT = 30000; // milliseconds
private WeakReference<GeolocationListener> mListener;
private LocationManager mLocationManager;
private Location mCurrentLocation;
private Timer mTimer;
public Geolocation(LocationManager locationManager, GeolocationListener listener)
{
mLocationManager = locationManager; // (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
mListener = new WeakReference<>(listener);
mTimer = new Timer();
init();
}
@Override
public void onLocationChanged(Location location)
{
Logcat.d(location.getProvider() + " / " + location.getLatitude() + " / " + location.getLongitude() + " / " + new Date(location.getTime()).toString());
// check location age
long timeDelta = System.currentTimeMillis() - location.getTime();
if(timeDelta > LOCATION_AGE)
{
Logcat.d("gotten location is too old");
// gotten location is too old
return;
}
// return location
mCurrentLocation = new Location(location);
stop();
GeolocationListener listener = mListener.get();
if(listener != null && location != null) listener.onGeolocationRespond(Geolocation.this, mCurrentLocation);
}
@Override
public void onProviderDisabled(String provider)
{
Logcat.d(provider);
}
@Override
public void onProviderEnabled(String provider)
{
Logcat.d(provider);
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras)
{
Logcat.d(provider);
switch(status)
{
case LocationProvider.OUT_OF_SERVICE:
Logcat.d("status OUT_OF_SERVICE");
break;
case LocationProvider.TEMPORARILY_UNAVAILABLE:
Logcat.d("status TEMPORARILY_UNAVAILABLE");
break;
case LocationProvider.AVAILABLE:
Logcat.d("status AVAILABLE");
break;
}
}
public void stop()
{
Logcat.d("");
if(mTimer != null) mTimer.cancel();
if(mLocationManager != null)
{
mLocationManager.removeUpdates(this);
mLocationManager = null;
}
}
private void init()
{
// get last known location
Location lastKnownLocation = getLastKnownLocation(mLocationManager);
// try to listen last known location
if(lastKnownLocation != null)
{
onLocationChanged(lastKnownLocation);
}
if(mCurrentLocation == null)
{
// start timer to check timeout
TimerTask task = new TimerTask()
{
public void run()
{
if(mCurrentLocation == null)
{
Logcat.d("timeout");
stop();
GeolocationListener listener = mListener.get();
if(listener != null) listener.onGeolocationFail(Geolocation.this);
}
}
};
mTimer.schedule(task, LOCATION_TIMEOUT);
// register location updates
try
{
mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0L, 0.0F, this);
}
catch(IllegalArgumentException e)
{
e.printStackTrace();
}
try
{
mLocationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0L, 0.0F, this);
}
catch(IllegalArgumentException e)
{
e.printStackTrace();
}
}
}
// returns last known freshest location from network or GPS
private Location getLastKnownLocation(LocationManager locationManager)
{
Logcat.d("");
Location locationNet = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
Location locationGps = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
long timeNet = 0L;
long timeGps = 0L;
if(locationNet != null)
{
timeNet = locationNet.getTime();
}
if(locationGps != null)
{
timeGps = locationGps.getTime();
}
if(timeNet > timeGps) return locationNet;
else return locationGps;
}
}