Android AsyncTask & LocationListener - android

I created a class GPSController. The onReceive is called every Minute.
I want to get the current GPS Data with the GPSListener in my AsyncTask.
But the onLocationChanged Method is never called. :-/
Here is my Class:
public class GPSController extends SensorTimeController {
// The minimum distance to change Updates in meters
private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 0;
// The minimum time between updates in milliseconds
private static final long MIN_TIME_BW_UPDATES = 2;
private boolean isGPSEnabled = false;
private boolean isNetworkEnabled = false;
private double latitude = -1;
private double longitude = -1;
private double altitude = -1;
private double speed = 0L;
private double bearing = 0L;
private LocationManager locationManager;
private GPSLocationTask backgroundTask;
public GPSController(GPSModule module) {
super(module);
backgroundTask = new GPSLocationTask();
}
private void SensorDataFinished(double longitude, double latitude, double altitude, double speed, double bearing) {
Date date = new Date(System.currentTimeMillis());
SensorRecord record = new SensorRecord(module.getNextIndex(), date, structure);
if (longitude != -1)
record.addData("longitude", String.valueOf(longitude));
else
record.addData("longitude", " ");
if (latitude != -1)
record.addData("latitude", String.valueOf(longitude));
else
record.addData("latitude", " ");
if (altitude != -1)
record.addData("altitude", String.valueOf(altitude));
else
record.addData("altitude", " ");
if (bearing != 0L)
record.addData("bearing", String.valueOf(bearing));
else
record.addData("bearing", " ");
if (speed != 0L)
record.addData("speed", String.valueOf(speed));
else
record.addData("speed", " ");
module.log(record);
}
#Override
public void onReceive(Context context, Intent intent) {
locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
backgroundTask.execute();
}
private class GPSLocationTask extends AsyncTask<Void, Void, Void> implements LocationListener {
#Override
protected Void doInBackground(Void... params) {
System.out.println("THREAD STARTED");
try {
Looper.prepare();
Looper.loop();
if(isNetworkEnabled)
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
if(isGPSEnabled)
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
}catch(SecurityException e) {
e.printStackTrace();
}
return null;
}
public void onLocationChanged(Location location) {
if (location != null) {
longitude = location.getLongitude();
latitude = location.getLatitude();
altitude = location.getAltitude();
// don't do anything if we get a null reading for some reason
if (longitude == 0.0f && latitude == 0.0f)
return;
// any speed information?
if (location.hasSpeed())
speed = (double) location.getSpeed();
// any bearing information?
if (location.hasBearing())
bearing = (double) location.getBearing();
System.out.println(longitude+", "+ latitude+", "+ altitude+", "+ speed+", "+ bearing);
SensorDataFinished(longitude, latitude, altitude, speed, bearing);
}
}
public void onProviderDisabled(String provider) {
}
public void onProviderEnabled(String provider) {
}
public void onStatusChanged(String provider, int status, Bundle extras) {
}
}
}

Related

Android GPS showing different location and counting wrong distance

i'm making app where i using GPS and counting traveled distance, i'm downloading current loaction and counting distance between two location. When i'm trying to get current location it is showing me different location (i don't move my phone) and when i'm trying to count distance i'm geting wrong result :/ here source code
GPSTracker:
public class GPSTracker extends Service implements LocationListener {
private final Context mContext;
public static double distance=0;
Location location1,location2;
boolean isGPSEnabled = false;
boolean isNetworkEnabled = false;
boolean canGetLocation = false;
Activity activity;
Location location;
double latitude;
double longitude;
private static final float MIN_DISTANCE_CHANGE_FOR_UPDATES = 50;
private static final long MIN_TIME_BW_UPDATES = 1000 * 10;
protected LocationManager locationManager;
public GPSTracker(Context context, Activity activity) {
this.mContext = context;
this.activity = activity;
getLocation();
}
public Location getLocation() {
try {
locationManager = (LocationManager) mContext.getSystemService(LOCATION_SERVICE);
isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (!isGPSEnabled && !isNetworkEnabled) {
} else {
this.canGetLocation = true;
if (isNetworkEnabled) {
int requestPermissionsCode = 50;
if (ContextCompat.checkSelfPermission(activity, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(activity, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, requestPermissionsCode);
} else {
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, mLocationListener);
if (locationManager != null) {
location = locationManager
.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
}
if(isGPSEnabled) {
if(location == null) {
if (ContextCompat.checkSelfPermission(activity, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(activity, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 50);
} else {
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, mLocationListener);
if (locationManager != null) {
location = locationManager
.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
}
}
}
} catch (Exception e){
e.printStackTrace();
}
return location;
}
private final LocationListener mLocationListener = new LocationListener() {
#Override
public void onLocationChanged(Location location) {
if(location != null){
latitude = location.getLatitude();
longitude = location.getLongitude();
}
if(location1 == null){
location1 = location;
} else {
location2 = location1;
location1 = location;
distance += location1.distanceTo(location2) / 1000f;
}
}
#Override
public void onStatusChanged(String s, int i, Bundle bundle) {
}
#Override
public void onProviderEnabled(String s) {
}
#Override
public void onProviderDisabled(String s) {
}
};
public double getLatitude(){
if(location != null){
latitude = location.getLatitude();
}
// return latitude
return latitude;
}
public double getLongitude(){
if(location != null){
longitude = location.getLongitude();
}
// return longitude
return longitude;
}
public boolean canGetLocation() {
return this.canGetLocation;
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onLocationChanged(Location location) {
}
#Override
public void onStatusChanged(String s, int i, Bundle bundle) {
}
#Override
public void onProviderEnabled(String s) {
}
#Override
public void onProviderDisabled(String s) {
}
}
DistanceActivity:
public class DistanceActivity extends Activity{
Button startB, stopB;
TextView textView;
GPSTracker gps;
Context mContext;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_distance);
startB = findViewById(R.id.start_B);
stopB = findViewById(R.id.stop_B);
textView = findViewById(R.id.distance_TV);
mContext = this;
startB.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
gps = new GPSTracker(mContext,DistanceActivity.this);
if(gps.canGetLocation()){
textView.setText("Distance: "+String.format("%.2f Km",gps.distance ));
} else {
textView.setText("Cannot count distance.");
}
}
});
}
}

Doesn't show actually position in locationManager in android

I creating an app to GPS tracking.
Unfortunetlly the app doesn't show actual location (lat,long). It always shows lat:50.059644 long:19.9206669. But I want to get and show the actual location of user(me).
It's my main activity:
Button btnShowLocation;
GPSTracker gps;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_about);
btnShowLocation = (Button) findViewById(R.id.btn1);
btnShowLocation.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
gps = new GPSTracker(About.this);
if(gps.canGetLocation()){
double latitude = gps.getLatitude();
double longitude = gps.getLongitude();
Toast.makeText(getApplicationContext(), "Your Location is - \nLat: " + latitude + "\nLong: " + longitude, Toast.LENGTH_LONG).show();
}else{
gps.showSettingsAlert();
}
}
});
}
And this is my GPS Tracker:
public class GPSTracker extends Service implements LocationListener{
private final Context mContext;
boolean isGPSEnabled = false;
boolean canGetLocation = false;
Location location;
private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; // 10 meters
private static final long MIN_TIME_BW_UPDATES = 1000 * 60 * 1; // 1 minute
protected LocationManager locationManager;
public GPSTracker(Context context) {
this.mContext = context;
getLocation();
}
public Location getLocation() {
try{
locationManager = (LocationManager) mContext.getSystemService(LOCATION_SERVICE);
isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
if(!isGPSEnabled) {
System.out.println("disabled");
//no network provider is enabled
} else {
this.canGetLocation = true;
if(isGPSEnabled){
System.out.println("gps wlaczony");
if (location == null){
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Log.d("GPS Enabled", "GPS Enabled");
if(locationManager != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
}
} catch(Exception e){
e.printStackTrace();
}
return location;
}
You request location updates here:
locationManager.requestLocationUpdates
but don't wait for the updates to come.
You have to register your requests and provide a listener to the onLocationChanged method. That method will be called when you have a new location.
Other than that, in order for the process to work you can't initialize GPSTracker every time the Btn is clicked. Do it once and wait for updates.
Try this:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_about);
btnShowLocation = (Button) findViewById(R.id.btn1);
btnShowLocation.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
gps = new GPSTracker(About.this);
}
});
}
public class GPSTracker extends Service implements LocationListener{
private final Context mContext;
boolean isGPSEnabled = false;
boolean canGetLocation = false;
Location location;
private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; // 10 meters
private static final long MIN_TIME_BW_UPDATES = 1000 * 60 * 1; // 1 minute
protected LocationManager locationManager;
public GPSTracker(Context context) {
this.mContext = context;
getLocation();
}
public Location getLocation() {
locationManager = (LocationManager) mContext.getSystemService(LOCATION_SERVICE);
isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
if(!isGPSEnabled) {
System.out.println("disabled");
//no network provider is enabled
} else {
this.canGetLocation = true;
if(isGPSEnabled){
System.out.println("gps wlaczony");
if (location == null){
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Log.d("GPS Enabled", "GPS Enabled");
if(locationManager != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
}
}
#Override
public void onLocationChanged(Location location) {
double latitude = location.getLatitude();
double longitude = location.getLongitude();
Toast.makeText(getApplicationContext(), "Your Location is - \nLat: " + latitude + "\nLong: " + longitude, Toast.LENGTH_LONG).show()
}
}

Sample GPS tracker with asynctask : error "provider doesn't exisit: null"

Im looking for a very sample example show longitude and latitude trackers with asynctask.
I find this code https://stackoverflow.com/a/6788457 but he doesn't work :/ i catch this strangely exception "provider doesn't exisit: null" in :
public boolean startService() {
try {
// this.locatorService= new
// Intent(FastMainActivity.this,LocatorService.class);
// startService(this.locatorService);
FetchCordinates fetchCordinates = new FetchCordinates();
fetchCordinates.execute();
return true;
} catch (Exception error) {
Log.i("exception", error.getMessage());
return false;
}
}
After search, I see this post (https://stackoverflow.com/a/13851305/2137454) who explain I must may be use this line :
List<String> providers = locationManager.getAllProviders();
But I don't understand where and how use this tips in my gpstracker class... Someone can help me ?
Here the complete gpstracker class :
public class GPSTracker extends Service implements LocationListener {
private final Context mContext;
boolean isGPSEnabled = false;
boolean isNetworkEnabled = false;
boolean canGetLocation = false;
Location location = null;
double latitude = 0;
double longitude = 0;
double altitude = 0;
private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10;
private static final long MIN_TIME_BW_UPDATES = 1000* 60 * 1;
protected LocationManager locationManager;
public GPSTracker(Context context) {
this.mContext = context.getApplicationContext();
getLocation();
}
public Location getLocation() {
try {
locationManager = (LocationManager) mContext.getSystemService(LOCATION_SERVICE);
isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (!isGPSEnabled && !isNetworkEnabled) {
Log.i("Je tombe...","...ici !");
} else {
this.canGetLocation = true;
if (isGPSEnabled) {
if (location == null) {
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Log.d("GPS Enabled", "GPS Enabled");
if (locationManager != null) {
location = locationManager
.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
altitude = location.getAltitude();
}
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return location;
}
public void stopUsingGPS() {
if (locationManager != null) {
Log.i("STOPUSINGGPS", "EFFECTIF");
locationManager.removeUpdates(GPSTracker.this);
}
}
public double getLatitude() {
if (location != null) {
Log.i("LATITUDE", "EFFECTIF");
latitude = location.getLatitude();
}
return latitude;
}
public double getLongitude() {
if (location != null) {
Log.i("LONGITUDE", "EFFECTIF");
longitude = location.getLongitude();
}
return longitude;
}
public double getAltitude() {
if (location != null) {
Log.i("ALTITUDE", "EFFECTIF");
altitude = location.getAltitude();
}
return altitude;
}
public boolean canGetLocation() {
return this.canGetLocation;
}
#Override
public void onLocationChanged(Location location) {
}
#Override
public void onProviderDisabled(String provider) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public IBinder onBind(Intent arg0) {
return null;
}
}
edit : my gps is turned ON

Why current location of android phone don't change when i change location?

I get location of android phone as:
android.location.Location locationA;
LocationManager locationManager;
Criteria cri = new Criteria();
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
String tower = locationManager.getBestProvider(cri, false);
locationA = locationManager.getLastKnownLocation(tower);
if (locationA != null) {
// lat = (double) (locationA.getLatitude() * 1E6);
// longi = (double) (locationA.getLongitude() * 1E6);
double lat = locationA.getLatitude();
double longi = locationA.getLongitude();
TextView txt = (TextView) findViewById(R.id.textView1);
String td = String.valueOf(lat) + "," + String.valueOf(longi);
txt.setText(td);
}
Why current location of android phone don't change when i change location and get again current location?
check the time of your location using locationA.getTime(). if it was not up to date wait for a new location and then stop.
private static Location currentLocation;
private static Location prevLocation;
public void yourMethod()
{
locationManager.requestLocationUpdates(provider, MIN_TIME_REQUEST,
MIN_DISTANCE, locationListener);
}
private static LocationListener locationListener = new LocationListener() {
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
#Override
public void onLocationChanged(Location location) {
gotLocation(location);
}
};
private static void gotLocation(Location location) {
prevLocation = currentLocation == null ?
null : new Location(currentLocation);
currentLocation = location;
if (isLocationNew()) {
// do something
locationManager.removeUpdates(locationListener);
}
}
private static boolean isLocationNew() {
if (currentLocation == null) {
return false;
} else if (prevLocation == null) {
return false;
} else if (currentLocation.getTime() == prevLocation.getTime()) {
return false;
} else {
return true;
}
}

Android locationManager - "location not changed" event

I'm building a service that will let me know if the location hasn't change in a period of time for a certain amount of metres.
Then thing is I have the event onLocationChanged on my Listener.. but I don't know how to do the opposite.. that is, send a broadcast if the location is within the distance I provided after some minutes.
This is the code I have so far
LocationService
public class LocationService extends Service {
public static final String LOC_INTENT = "com.xxx.intent.action.LOCATION";
private Thread triggerService;
protected LocationManager locationManager;
protected MyLocationListener MyLocationListener;
protected Criteria criteria;
public static final int MIN_TIME = 300000; // 5 Minutes
public static final long MIN_DISTANCE_MOTOR = 50; // 50 Metres
private SharedPreferences settings;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
settings = getSharedPreferences(getString(R.string.settings_prefsName), 0);
addLocationListener();
return START_STICKY;
}
private void addLocationListener()
{
triggerService = new Thread(new Runnable(){
public void run(){
try{
Looper.prepare();//Initialise the current thread as a looper.
locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
final String PROVIDER = locationManager.getBestProvider(criteria, true);
updateLocation(getLastBestLocation(MIN_TIME, MIN_DISTANCE_MOTOR));
MyLocationListener = new MyLocationListener();
locationManager.requestLocationUpdates(PROVIDER, MIN_TIME, MIN_DISTANCE_MOTOR, MyLocationListener);
Log.d("LOC_SERVICE", "Service RUNNING! ("+PROVIDER+")");
Looper.loop();
}catch(Exception ex){
ex.printStackTrace();
}
}
}, "LocationThread");
triggerService.start();
}
public Location getLastBestLocation(int minDistance, long minTime) {
Location bestResult = null;
float bestAccuracy = Float.MAX_VALUE;
long bestTime = Long.MIN_VALUE;
List<String> matchingProviders = locationManager.getAllProviders();
for (String provider: matchingProviders) {
Location location = locationManager.getLastKnownLocation(provider);
if (location != null) {
float accuracy = location.getAccuracy();
long time = location.getTime();
if ((time > minTime && accuracy < bestAccuracy)) {
bestResult = location;
bestAccuracy = accuracy;
bestTime = time;
}
else if (time < minTime && bestAccuracy == Float.MAX_VALUE && time > bestTime) {
bestResult = location;
bestTime = time;
}
}
}
return bestResult;
}
public static void updateLocation(Location location)
{
Context appCtx = MyApplication.getAppContext();
double latitude, longitude;
float speed;
latitude = location.getLatitude();
longitude = location.getLongitude();
speed = location.getSpeed();
Intent filterRes = new Intent();
filterRes.setAction(LOC_INTENT);
filterRes.putExtra("latitude", latitude);
filterRes.putExtra("longitude", longitude);
filterRes.putExtra("speed", speed);
appCtx.sendBroadcast(filterRes);
}
class MyLocationListener implements LocationListener
{
#Override
public void onLocationChanged(Location location)
{
if(settings.getBoolean("active", false))
updateLocation(location);
}
#Override
public void onProviderDisabled(String provider) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
}
}
Set a timer for however long you want to test this. When it goes off, check if the last location you got in onLocationChanged is older than the timer length.
EDIT
Here is how I would imagine your service looking
Service starting
requestLocationUpdates called with appropriate minimum time and minimum distance that that you will be notified after
Repeating task set where you check if an update was received (check out Timer.scheduleAtFixedRate
Service running
Perform necessary actions when your timer goes off or onLocationChanged is called
Service stopping
Remove location updates with removeUpdates
Stop your timer

Categories

Resources