Reputation: 194
I've recently been working on simple speed calculations for an application I'm working on, but the code I have takes far too long to retrieve the location, and I know that questions like this have been asked before, but none of the answers seem to retrieve the results I'm looking for. So, how can I make this code have gps fixes within a matter of seconds, and is it even possible? My LocationListener:
package me.dylan.acf;
import java.text.DecimalFormat;
import java.util.ArrayList;
import android.app.NotificationManager;
import android.location.Location;
import android.location.LocationListener;
import android.os.Bundle;
import android.text.format.Time;
import android.widget.TextView;
public class GPSManager implements LocationListener {
ArrayList<Double> avgspeeds = new ArrayList<Double>();
TextView debug;
NotificationManager mngr;
double avgspeed;
long lastTime = 0;
GraphView view;
Location lastloc;
int earthRadius = 6371;
long delaytime = 30;
ArrayList<Double> allspeeds = new ArrayList<Double>();
public GPSManager(TextView view) {
debug = view;
Location location = ACF.instance.lmanager
.getLastKnownLocation(ACF.instance
.getProperLocationsServices(ACF.instance
.getApplicationContext()));
if (location != null) {
double speed = location.getSpeed();
lastloc = location;
debug.setText("Average Speed: " + avgspeed + "\nCurrent speed: "
+ speed + "\nLocation updates: " + avgspeeds.size());
}
}
@Override
public void onLocationChanged(Location location) {
// DecimalFormat format = new DecimalFormat("0.00");
double speed = location.getSpeed();
if (lastloc != null) {
double latDist = Math.toRadians(location.getLatitude()
- lastloc.getLatitude());
double lonDist = Math.toRadians(location.getLongitude()
- lastloc.getLongitude());
double lat1 = Math.toRadians(location.getLatitude());
double lat2 = Math.toRadians(lastloc.getLatitude());
double a = Math.sin(latDist / 2) * Math.sin(latDist / 2)
+ Math.sin(lonDist / 2) * Math.sin(lonDist / 2)
* Math.cos(lat1) * Math.cos(lat2);
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
double dist = earthRadius * c;
speed = (dist * 0.621371) / Math.abs(System.currentTimeMillis() - lastTime * 60 * 60 * 60);
lastTime = System.currentTimeMillis();
}
allspeeds.add(speed);
if (allspeeds.size() > 30) {
allspeeds.remove(0);
}
avgspeed = 0;
for (double d : allspeeds) {
avgspeed += d;
}
avgspeed /= allspeeds.size();
// avgspeed = Double.parseDouble(format.format(avgspeed));
avgspeeds.add(avgspeed);
lastloc = location;
debug.setText("Average Speed: " + avgspeed + "\nCurrent speed: "
+ speed + "\nLocation updates: " + avgspeeds.size());
}
@Override
public void onProviderDisabled(String provider) {
}
@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
}
}
Where I call it:
public void updateWithProperService() {
lmanager.requestSingleUpdate(
getProperLocationsServices(getApplicationContext()), GPSmngr,
null);
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
updateWithProperService();
}
}, 10000);
}
public String getProperLocationsServices(Context context) {
if (lmanager == null)
lmanager = (LocationManager) context
.getSystemService(Context.LOCATION_SERVICE);
int minTime = 3000;
/*
* boolean isGPS = false; boolean isNetwork = false; try { isGPS =
* lmanager.isProviderEnabled(LocationManager.GPS_PROVIDER); } catch
* (Exception e) { e.printStackTrace(); } try { isNetwork = lmanager
* .isProviderEnabled(LocationManager.NETWORK_PROVIDER); } catch
* (Exception e) { e.printStackTrace(); }
*/
List<String> matchingProviders = lmanager.getAllProviders();
Location bestResult = null;
long bestTime = 0;
for (String provider : matchingProviders) {
Location location = lmanager.getLastKnownLocation(provider);
if (location != null) {
// float accuracy = location.getAccuracy();
long time = location.getTime();
// float bestAccuracy;
/*
* if ((time > minTime && accuracy < bestAccuracy )) {
* bestResult = location; bestTime = time; } else
*/if (time < minTime &&
/* bestAccuracy == Float.MAX_VALUE && */time < bestTime) {
bestResult = location;
bestTime = time;
}
}
}
if (bestResult != null)
return bestResult.getProvider();
else
return LocationManager.NETWORK_PROVIDER;
}
Upvotes: 0
Views: 125
Reputation: 28727
gps needs about 15 seconds if it was disabled before and when using Assisted GPS. you cannot improve that.
Whitout AGPS it needs 25-35 seconds, under good conditions. The term is called "Time to First fix" (TTF).
Upvotes: 0
Reputation: 116362
google has released a nice API on their recent Google IO 2013 event:
https://developers.google.com/events/io/sessions/324498944
you should check it out and see how you can minimize your code.
do note that it requires that the device would have the play store app for this to work.
this method has many advantages over using the normal location sensors (battery, speed , accuracy,...) .
Upvotes: 1