Avoid get multiple location when device is still stable in gps android - android

i using simple Listner Class for get location in onchage location
but the device is stable then gps is getting wrong lat long and get multliple location up to in 1000 meter.
MyLocationListener.java
public class MyLocationListener implements LocationListener{
#Override
public void onLocationChanged(Location location) {
// Toast.makeText(getBaseContext(), "change time", 5).show();
if(location.getAccuracy() < 100.0 && location.getSpeed() >0.95){
Log.v("ddddddd", "fffffffff"+location.getLongitude()+location.getProvider());
// if (location.hasAccuracy() && location.getAccuracy() <= minAccuracyMeters){
accuracy=location.getAccuracy();
longitude=location.getLongitude();
latitude=location.getLatitude();
speed=(int) ((location.getSpeed()*3600)/1000);
}
}
Please Help me i new in android i will workin on GPS last two month.

Filter the locations this way,
public static final int MINIMUM_ACCURACY = 50;
public static boolean isValidAndAccurateLocation(Location location) {
boolean validLocation = location != null
&& Math.abs(location.getLatitude()) <= 90
&& Math.abs(location.getLongitude()) <= 180;
if (validLocation && location.hasAccuracy()
&& location.getAccuracy() <= MINIMUM_ACCURACY) {
return true;
} else {
return false;
}
}

Provide minimum distance when requesting location updates, No need to calculate distance manually. use
mLocationManger.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, time, distance,
this);
Where time is time in milliseconds and distance is minimum distance in meters. See this for full explanation.

Related

How to update the blue dot marker for current location in MapView in Android

I have a fragment which when normally launched shows a mapview with current user location shown as blue dot marker. I have a feature to launch this screen from another place and can pass latitude and longitude values. Based on these values, I update the latitude and longitude of "MapboxMap". The location is updated on map and camera zooms to it but blue dot marker still shows as user current location. How can I update the blue dot marker to be shown as new location given by latitude and longitude value:
My code to update location:
private void goToUserLocation() {
double requestedLatitude = 0;
double requestedLongitude = 0;
if (mapboxMap == null || !getUserVisibleHint()) {
return;
}
if (!DeviceUtil.isLocationServiceEnabled(getContext().getApplicationContext())) {
showLocationDisabledSnackbar();
return;
}
enableUserLocationMarker();
Location location = mapboxMap.getMyLocation();
//Get the requested coordinates if it exists
if(location != null) {
try {
Uri intentData = getActivity().getIntent().getData();
if (null != intentData) {
String latitude = intentData.getQueryParameter("lat");
String longitude = intentData.getQueryParameter("lon");
if (!TextUtils.isEmpty(latitude) && !TextUtils.isEmpty(longitude)) {
requestedLatitude = Double.parseDouble(latitude);
requestedLongitude = Double.parseDouble(longitude);
if ((requestedLatitude >= -90 && requestedLatitude <= 90) &&
(requestedLongitude >= -90d && requestedLongitude <= 90d)) {
location.setLatitude(requestedLatitude);
location.setLongitude(requestedLongitude);
}
}
}
}catch (NumberFormatException ex) {
}
finally {
goToLocation(location);
}
}
fetchNearbyPages();
}
Any help is appreciated.
Hi hope this will help.
First, override the onLocatioChanged method and pass the updated location to separate created setCameraToCurrentPosition method. ex. is as follows:-
public void onLocationChanged(Location location) {
setCameraToCurrentPosition(Location location);
}
private void setCameraToCurrentPosition(Location location) {
setCameraPosition(new LatLng(location.getLatitude(), location.getLongitude()), 16, 6500);
// Here you need to add the marker to current position of user on map.
}

Android Fused Location API gives inaccurate Location in onLocationChanged

I am struggling a little here, I am using Fused API for getting location updates. My intention is to draw a path on Map when user walks.
I have implemented that as follows :
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.map_layout, container, false);
// some other initialization
//....
//
if (mGoogleApiClient == null) {
mGoogleApiClient = new GoogleApiClient.Builder(mContext)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
return view;
}
then I start the stuff by following method
private void startReceivingLocationUpdates() {
if (checkGPSPermission() && mGoogleApiClient.isConnected() && !isReceivingLocationUpdates) {
LocationRequest locationRequest = new LocationRequest();
locationRequest.setInterval(5000);
locationRequest.setFastestInterval(5000);
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient,
locationRequest, this);
isReceivingLocationUpdates = true;
}
}
& Here I receive the location update
#Override
public void onLocationChanged(Location location) {
if(getDistanceBetweenTwoLacation(mCoordinates.get(mCoordinates.size() - 1), location) > 3d) {
for(int i= 0; i < mCoordinates.size(); i++) {
Location locationTemp = mCoordinates.get(i);
Log.d(TAG, "i => " + i + " Lat => " + String.valueOf(locationTemp.getLatitude()) + " Lng => " + String.valueOf(locationTemp.getLongitude()));
}
if(mCoordinates.size() > 0)
Log.d(TAG, "lat difference is => " + getDistanceBetweenTwoLacation(mCoordinates.get(mCoordinates.size() - 1), location));
mCoordinates.add(location);
}
}
Now the problem is , onLocationChanged gives location with lat-lng whose difference/distance from past location is about 5-90 meters many times even if device is steady on same place. Am I missing something?
btw, here's the method which returns the distance from two lat-lngs which I used
private double getDistanceBetweenTwoLacation(Location origin, Location destination) {
return origin.distanceTo(destination);
}
Inaccurate (and moving/drifting/jumping) GPS fixes when indoors is pretty common. Without a clear view of the sky, an accurate GPS fix is impossible. In your Location object, there is a getAccuracy() method which returns a float. This value is the accuracy of the position fix in meters, wit 68% (1 standard deviation) confidence and represents the radius of a circle.
While indoors you will probably see an accuracy value of 20, 30, perhaps even 50 meters while the Lat & Long jump around within that distance. Once outdoors, the accuracy value should drop to under 10 meters, often under 5 meters, and your position will jump around much less frequently.
tl;dr : GPS doesn't give accurate results indoors.

GPS - Getting the distance,time while running and walking

i have a situation where i need to use GPS technique.
i need to find the distance between two points when the person is walking.
When the person starts walking he will click on Start button and when he stops he clicks on stop button
after this it should show him
1.time taken
2.Distance travelled in Kms.
3.from where to where(places name) eg: a to b
Do i need to have google maps for this?
I saw the code here link to get the current location which gives me latitude longitude.
please help how to go with this
**
Edited:
**
This is the code i am using
private EditText editTextShowLocation;
private Button buttonGetLocation;
private ProgressBar progress;
private LocationManager locManager;
private LocationListener locListener = new MyLocationListener();
private boolean gps_enabled = false;
private boolean network_enabled = false;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
editTextShowLocation = (EditText) findViewById(R.id.editTextShowLocation);
progress = (ProgressBar) findViewById(R.id.progressBar1);
progress.setVisibility(View.GONE);
buttonGetLocation = (Button) findViewById(R.id.buttonGetLocation);
buttonGetLocation.setOnClickListener(this);
locManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
}
#Override
public void onClick(View v) {
progress.setVisibility(View.VISIBLE);
// exceptions will be thrown if provider is not permitted.
try {
gps_enabled = locManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
} catch (Exception ex) {
}
try {
network_enabled = locManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
} catch (Exception ex) {
}
// don't start listeners if no provider is enabled
if (!gps_enabled && !network_enabled) {
AlertDialog.Builder builder = new Builder(this);
builder.setTitle("Attention!");
builder.setMessage("Sorry, location is not determined. Please enable location providers");
builder.setPositiveButton("OK", this);
builder.setNeutralButton("Cancel", this);
builder.create().show();
progress.setVisibility(View.GONE);
}
if (gps_enabled) {
locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locListener);
}
if (network_enabled) {
locManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locListener);
}
}
class MyLocationListener implements LocationListener {
#Override
public void onLocationChanged(Location location) {
if (location != null) {
// This needs to stop getting the location data and save the battery power.
locManager.removeUpdates(locListener);
String londitude = "Londitude: " + location.getLongitude();
String latitude = "Latitude: " + location.getLatitude();
String altitiude = "Altitiude: " + location.getAltitude();
String accuracy = "Accuracy: " + location.getAccuracy();
String time = "Time: " + location.getTime();
editTextShowLocation.setText(londitude + "\n" + latitude + "\n" + altitiude + "\n" + accuracy + "\n" + time);
progress.setVisibility(View.GONE);
}
}
#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
public void onClick(DialogInterface dialog, int which) {
if(which == DialogInterface.BUTTON_NEUTRAL){
editTextShowLocation.setText("Sorry, location is not determined. To fix this please enable location providers");
}else if (which == DialogInterface.BUTTON_POSITIVE) {
startActivity(new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS));
}
}
It is showing the Logitude Latitude which i am entering from emulator control.
In this i am manually entering the details of longitude and latitude
by going to window->showview->other->emulator control for testing in the emulator
but what i need is i will have two edittext where i enter the place name(A) and (B)
it should give me the distance
please help
try using Google Distance Matrix Api
https://developers.google.com/maps/documentation/distancematrix/
You can use currentTimeinMillis() to get your start and end time for your journey.
You can then use the formulas explained here to find the distance and lastly you will have to use a reverse geocoding service such as Nominatim to be able to get the address of a place from your GPS coordinates.
That being said, the distance formula will get you the distance between one point and the next, not the actual displacement. If this is not what you need, but rather you want the actual distance travelled you will need to calculate this value at a shorter interval.
You can find out the distance between two locations(in terms of latitude and longitude) by making use of Spherical Trigonometry
Coming to time make use of simple date objects and compare the startTime and endTime.
(OR)
You can get approximate distance using below code
double distance;
Location locationA = new Location("point A");
locationA.setLatitude(latA);
locationA.setLongitude(lngA);
Location locationB = new Location("point B");
locationB.setLatitude(latB);
LocationB.setLongitude(lngB);
distance = locationA.distanceTo(locationB);
For getting the distance between 2points(A to B) there is a function called distanceTo in android.
For e.g.
double distance = startLocation.distanceTo(finishLocation)/1000;
For time taken as npinti said you can use currentTimeinMillis() or you can also use Timer and show it to user when he clicks on start button. Its just like stopwatch.
Edited
Place A - New York
Place B - Paris
In this case you first need to convert the string into Location(i.e you need latitude & longitude). For that you have use the concept of Geocoding.
List<Address> foundGeocode = null;
foundGeocode = new Geocoder(this).getFromLocationName("address here", 1);
foundGeocode.get(0).getLatitude(); //getting latitude
foundGeocode.get(0).getLongitude();//getting longitude
After that you can calculate the distance from the distanceTo method.
Hope this will help....
I suppose the question is one of walking..
Are you walking on the streets, or as the crow flies?
If it's streets, and your connected to the net, use google's api.. It calculates routing based on two points and returns XML.. Should be easy enough to figure out.
If it's crow flies.. well then, just do (a*a) + (b*b) = (c*c) this is by far the easier..
You could have your user tap for major turns.. Or you could keep a runnable running every 10 seconds from when they hit start, and plot the points. Still a*a+b*b=c*c but just a bunch of steps.
Of course you'd have to run it in a service.. And given the choice I'd go with that option. You could adjust the cycle time based on speed traveled. Faster would be smaller pauses.
It requires less on your dataplan.
EDIT
Ah.. I see what you're looking for. Tis not what I thought you were asking for.
Simplify.. convert lat/long to GPS. and then do simple math on the last point stored
void addDistance()
{
newX = ...
newY = ...
deltaX = absolute(m_oldX - newX)
deltaY = absolute(m_oldY = newY)
m_distance += sqrt(deltaX^2 + deltaY^2);
m_oldX = newX;
m_oldY = newY;
}
void startOver()
{
newX = ...
newY = ...
m_distance = 0;
m_oldX = newX;
m_oldY = newY;
}

How to get the latitude and longitude or gps data quickly while we are indoor in an android phone?

I'm trying to get the latitude and longitude information from an android phone through GPS, when i'm outdoor or under the sky directly i'm able to get the values instantly but when i'm indoor or inside a room its taking more than a minute to get the values. Can anyone help me in getting this values fastly when I'm using my app inside a room.
I'm using the following code in getting the values:
LocationManager locManager;
locManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,1000L,500.0f,
locationListener);
Location location = locManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
and
private final LocationListener locationListener = new LocationListener() {
public void onLocationChanged(Location location) {
EditText myLocationText = (EditText)findViewById(R.id.editText1);
EditText myLocationText1 = (EditText)findViewById(R.id.editText2);
String latString = "";
String LongString = "";
if (location != null) {
double lat = location.getLatitude();
double lng = location.getLongitude();
latString = "" + lat;
LongString ="" + lng;
} else {
latString = "No location found";
LongString = "No location found";
}
myLocationText.setText(""+ latString);
myLocationText1.setText(""+ LongString);
}
Is there any other way in getting the GPS values other than using LocationManager??
You can get the last known location, and it's quite fast:
/**
* Gets the last known location.
*
* #param locationManager the location manager
* #return the last known location
*/
public static Location getLastKnownLocation(LocationManager locationManager)
{
Location bestResult = null;
float bestAccuracy = 10000;
long bestTime = 0;
List<String> matchingProviders = locationManager.getAllProviders();
for (String provider: matchingProviders) {
Log.d("LOCATION", "Provider: " + provider);
Location location = locationManager.getLastKnownLocation(provider);
Log.d("LOCATION", "Location found? "+ (location==null?"NO":"YES"));
if (location != null) {
float accuracy = location.getAccuracy();
long time = location.getTime();
Log.d("LOCATION", "Acc: "+ String.valueOf(accuracy) + " -- Time: " + String.valueOf(time));
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;
}
}
}
Log.d("LOCATION", "BEST FOUND? "+ (bestResult==null?"NO":"YES"));
return bestResult;
}
You can get the last known location of the device using the following method in LocationManager, this is the location that has been last found system-wide.
This method is the key:
Location lastKnownLocation = locationManager.getLastKnownLocation(locationProvider);
See for more details Obtaining User Location
If you are indoors, you would be better of using LocationManager.NETWORK_PROVIDER as you are unlikely to get a signal inside. You could also use getLastKnownLocation(), but this may be non existent or out of date.
If you want get position in a room, gps provider is slowly. You can try changing:
locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,1000L,500.0f,
locationListener);
Location location = locManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
By:
locManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,1000L,500.0f,
locationListener);
And you will receive location in 'public void onLocationChanged(Location location)' method.
I used Network provider to fetch the Co-Ordinates and it is always much faster inside the house in living room. But when I try the same in the Basement area, it doesn't fetch the coordinates at all though I waited almost couple of minutes.
Note: I could able to make a call from basement area and I am also able to browse as well..

Implementing Kalman filter with Fusion Provider in Android for GPS positions

I have to implement Kalman filter for a better accuracy with GPS positions... I use Stochastically solution (Smooth GPS data). In ValidPosition I have some checks like:
public boolean checkPosition(Location location) {
if (( location != null ) &&
(distance != 0) &&
(distance > MINIMUM_DISTANCE) && // 10 metres
(location.hasSpeed()) &&
(location.getSpeed() > 0) &&
(averageTime < HUMANSPEED) &&
(location.hasAccuracy()) &&
(location.getAccuracy() < MINIMUM_ACCURACY) &&
(isBetterLocation(location, lastLocation)) // From Google example in http://developer.android.com/guide/topics/location/strategies.html#BestPerformance
return true;
}
return false;
}
Now, in my main class with Location Fusion Provider I have this:
public static final int ACCURACY_DECAYS_TIME = 3; // Metres per second
private KalmanLatLong kalmanLatLong = new KalmanLatLong(ACCURACY_DECAYS_TIME);
private ValidPosition validPosition = new ValidPosition();
#Override
public void onLocationChanged(Location location) {
if(validPosition.checkPosition(location)) {
kalmanLatLong.process(
location.getLatitude(),
location.getLongitude(),
location.getAccuracy(),
location.getTime());
mCallback.handleNewLocation(location);
}
}`
And now? How can I use Kalman predictions? What do I have write here in Stochastically code?
// TODO: USE VELOCITY INFORMATION HERE TO GET A BETTER ESTIMATE OF CURRENT POSITION
Thanks
You forgot to get processed result back from the kalmanLatLong object.
You need to do something like this:
if(validPosition.checkPosition(location)) {
kalmanLatLong.process(
location.getLatitude(),
location.getLongitude(),
location.getAccuracy(),
location.getTime());
location.setLatitude(kalmanLatLong.get_lat());
location.setLongitude(kalmanLatLong.get_lng());
location.setAccuracy(kalmanLatLong.get_accuracy());
mCallback.handleNewLocation(location);
}
As for your second question, I don't think it's trivial and should be based more on experimental data. Simple assumption with linear decay works well in most cases.

Categories

Resources