Any way to delay getLatKnownLocation? Android GPS - android

So i am using the getLastKnownLocation method to get the Location loc of the device but it returns null unless there is a GPS fix. Is there a way to delay execution of getLastKnownLocation until the GPS has a valid location to provide?
package test.example;
import android.app.Activity;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.Toast;
public class testGPS extends Activity
{
private LocationManager lm;
private LocationListener locationListener;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TextView tv = new TextView(this);
//---use the LocationManager class to obtain GPS locations---
lm = (LocationManager)
getSystemService(Context.LOCATION_SERVICE);
locationListener = new MyLocationListener();
lm.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
0,
0,
locationListener);
Location loc = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (loc != null) {
tv.setText("Hello, lat is " + loc.getLatitude() + " lon is " + loc.getLongitude());
setContentView(tv);
} else {
tv.setText("Hello, loc is null :(");
setContentView(tv);
}
}
private class MyLocationListener implements LocationListener
{
#Override
public void onLocationChanged(Location loc) {
}
#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
}
}
}

You're misunderstanding how location works in Android. getLastKnownLocation() doesn't provide null unless the GPS has a fix, it returns null if there's no previous known location - the location does not have to come from the GPS (it could come via wifi or mobile network) and calling that method does not instruct the location framework to return a new location.
You need to start again, after fully reading and understanding this page:
http://developer.android.com/guide/topics/location/obtaining-user-location.html
It includes everything you need to handle locations in Android, and you need a framework that suits the needs of your application. If you want the location to persist (to reduce the use of the GPS) then you can save the location to preferences, and/or enable network location sending (not as accurate, but usually faster). For some apps you may want to grab a rough location quickly (using last-known, or the network location provider) and then update it when an accurate GPS location arrives. But the approach you use will vary by app.

Related

Location service giving me null on some phones android

I created a service for getting user Location which I am calling from my main thread. Now, this service is getting my location not just from gps, but also from network. Why is it getting user Location on some phones and on some phones it doesnt?
Here is my service class:
import android.app.Service;
import android.content.Intent;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import java.util.List;
public class LocationService extends Service implements LocationListener {
protected LocationManager locationManager;
public String providerNow;
private List<String> providers;
public Location location;
public LocationService() {
}
#Override
public void onCreate() {
super.onCreate();
locationManager = (LocationManager) this.getSystemService(LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 0, this);
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1000, 0, this);
providerNow = (GetProvider());
}
public Location getLocation() {
location = locationManager.getLastKnownLocation(providerNow);
return location;
}
public String GetProvider() {
Criteria criteria = new Criteria();
criteria.setAccuracy(2);
providers = locationManager.getProviders(true);
String providerToSend = providers.get(1);
return providerToSend;
}
public IBinder onBind(Intent intent) {
Log.i("TestMap", "onBind");
//TODO for communication return IBinder implementation
return null;
}
public void onLocationChanged(Location location) {
Static.location = location;
if (location != null) {
Log.d("Lat", String.valueOf(location.getLatitude()));
Log.d("Lon", String.valueOf(location.getLongitude()));
Static.latitude = location.getLatitude();
Static.longitude = location.getLongitude();
}
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
providerNow = (GetProvider());
}
#Override
public void onProviderDisabled(String provider) {
providerNow = (GetProvider());
}
}
Here is the code from main thread where I am calling this service:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash_screen);
Intent serviceIntent = new Intent(this, LocationService.class);
startService(serviceIntent);
proveraInterneta();
getSizeOfTheScreen();
}
Here are the two suggestions for the issue you are facing:
As per coding, make use of the Google's Fused Location API. FusedLocationProviderApi can be accessed via LocationServices as below,
private FusedLocationProviderApi fusedLocationProviderApi = LocationServices.FusedLocationApi;
FusedLocationProviderApi requires the GoogleApiClient instance to get the Location and it can be obtained as below.
googleApiClient = new GoogleApiClient.Builder(locationActivity)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
Secondly, from device perspective make sure that the GPS is turned on all the devices under test.
Last but not the least, check if this permission is added in the manifest.
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
Take a look at this tutorial for more reference.
As i understand your code, when you call getLocation method then obtain latest location from currently working provider (or latest enabled provider). When you enable a provider, it's not guaranteed getting location from getLocation method.
if i call getLastKnownLocation("gps") right after making enabled gps provider, it so normal getting null result. Because gps provider must fire onLocationChanged method at least one time, so i have to wait for gps fix. Also this scenario is same for network provider too.
Calling getLastKnownLocation("a provider") method without being sure about the provider is fixed, will give you unreliable(old location) or null result. In this case, if some phones doesn't give null, it means these devices have cached location for current provider or they are lucky because the provider is warmed up already

how to detect location in android very fastly

my android application can detect longitude and latitude. but it take some time. my app has 9 activates and last activity should send location to data base. any one can give a solution for this. i want to detect location soon as possible, what did missed in my code?
package com.example.zlocation;
import android.app.Activity;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
public class MainActivity extends Activity implements LocationListener{
protected LocationManager locationManager;
protected LocationListener locationListener;
protected Context context;
protected TextView txtLat;
String lat;
String provider;
protected String latitude,longitude;
protected boolean gps_enabled,network_enabled;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
txtLat = (TextView) findViewById(R.id.textView1);
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
}
#Override
public void onLocationChanged(Location location) {
txtLat = (TextView) findViewById(R.id.textView1);
txtLat.setText("Latitude:" + location.getLatitude() + ", Longitude:" + location.getLongitude());
}
#Override
public void onProviderDisabled(String provider) {
Log.d("Latitude","disable");
}
#Override
public void onProviderEnabled(String provider) {
Log.d("Latitude","enable");
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
Log.d("Latitude","status");
}
}
You are trying to get the location from gps provider.The problem with gps is however vit is accurate but it takes time in starting the gps and providing a location it can take anything from 2-30 seconds to provide the location if you want location as soon as possible have a look at fused location provider by google and implement it in that you can define the time after you want the location updates or from my personal experience i would suggest you to have a look at littlefluffy location library it is easier to implement.

How to set max time to LocationManager in android?

I am working on geo-loaction applciation where I need to calculate user speed, to get user speed I used LocationManager for their current location after every 30second, for this I used following code.
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1000*30, 0, myLocationListener); //from NETWORK_PROVIDER
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000*30, 0, myLocationListener); //from GPS_PROVIDER
But my problem is I want location based on fix time interval here is 30second. Right now I get location after every 45second also vary. So if any know how I can set 'maxTime' to location manager then please let me know.
Also if any one know the location listener calling business logic based on time / distance also please let me know.
Thanks in advanced.
Use the new introduced Fused Location Provider API
import android.app.IntentService;
import android.content.Intent;
import android.location.Location;
import android.os.Bundle;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesClient;
import com.google.android.gms.location.LocationClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
public class Locations extends IntentService implements
GooglePlayServicesClient.ConnectionCallbacks,
GooglePlayServicesClient.OnConnectionFailedListener, LocationListener {
public Locations() {
super("Locations");
Log.d("Locations", "Location service started... ");
}
private LocationRequest locationRequest;
private LocationClient locationClient;
private Location location;
private static final int INTERVAL = 1800000;
private static final int FASTEST_INTERVAL = 60000;
#Override
protected void onHandleIntent(Intent intent) {
locationRequest = LocationRequest.create();
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
locationRequest.setInterval(INTERVAL);
locationRequest.setFastestInterval(FASTEST_INTERVAL);
locationClient = new LocationClient(this, this, this);
locationClient.connect();
}
#Override
public void onLocationChanged(Location l) {
// do something on Location change.
}
#Override
public void onConnectionFailed(ConnectionResult arg0) {
}
#Override
public void onConnected(Bundle arg0) {
Log.w("Locations", "Location client connected...");
// get last location
location = locationClient.getLastLocation();
Log.w("Locations", "Latitude : "+location.getLatitude() + "");
Log.w("Locations", "Longitude : "+location.getLongitude() + "");
}
#Override
public void onDestroy() {
if (locationClient.isConnected()) {
locationClient.removeLocationUpdates(this);
}
locationClient.disconnect();
}
#Override
public void onDisconnected() {
}
}
Source https://developer.android.com/training/location/index.html

Which Class Should I call locationManger.removeUpdates() from?

So, I have an Android application that is asking for the GPS from the LocationManager class.
I have an Activity that wants to use that data, and a custom class that implements LocationListener.
I have written some custom methods to return the GPS values to my other class.
Currently, I am asking for and releasing the location updates from my Activity class, not my implementation of the LocationListener class... I think this is the right way to go about it, but I just wanted to get any feedback on the life cycle, etc. (the class that implements LocationListener is not an Activity, so I don't think I even could call onPause() etc, ?)
This is the Activity:
package com.jessescott.sonicity;
import android.app.Activity;
import android.content.Context;
import android.view.View;
import android.widget.TextView;
import android.location.Location;
import android.location.LocationManager;
import android.location.LocationListener;
public class PlayActivity extends Activity {
// GLOBALS
private static final String TAG = "SoniCity";
LocationManager locationManager;
MyLocationListener locationListener;
TextView latitude, longitude;
TextView ActualLatitude, ActualLongitude;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.play_layout);
// GPS
locationListener = new MyLocationListener(this);
// TextViews
latitude = (TextView) findViewById(R.id.Latitude);
longitude = (TextView) findViewById(R.id.Longitude);
ActualLatitude = (TextView) findViewById(R.id.ActualLat);
ActualLatitude.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.v(TAG, "Asking For New Latitude");
ActualLatitude.setText(locationListener.getCurrentLatitude());
}
});
ActualLongitude = (TextView) findViewById(R.id.ActualLon);
ActualLongitude.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.v(TAG, "Asking For New Latitude");
ActualLongitude.setText(locationListener.getCurrentLongitude());
}
});
}
#Override
protected void onPause() {
super.onPause();
// Stop GPS
locationManager.removeUpdates(locationListener);
locationManager = null;
}
#Override
protected void onResume() {
super.onResume();
locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 2000, 5, locationListener);
}
#Override
public void onDestroy() {
super.onDestroy();
}
} /* */
... and this is the LocationListener implementation :
package com.jessescott.sonicity;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.os.Bundle;
import android.util.Log;
class MyLocationListener implements LocationListener {
private static final String TAG = "SoniCity";
float currentLatitude = 0;
float currentLongitude = 0;
public MyLocationListener(Context context) {
super();
}
// Define all LocationListener methods
public void onLocationChanged(Location location) {
currentLatitude = (float)location.getLatitude();
currentLongitude = (float)location.getLongitude();
}
public void onProviderDisabled (String provider) {
Log.v(TAG, "Provider is " + provider);
}
public void onProviderEnabled (String provider) {
Log.v(TAG, "Provider is " + provider);
}
public void onStatusChanged (String provider, int status, Bundle extras) {
Log.v(TAG, "Status is " + status);
}
// Custom Methods
public String getCurrentLatitude() {
String lat = Float.toString(currentLatitude);
return lat;
}
public String getCurrentLongitude() {
String lon = Float.toString(currentLongitude);
return lon;
}
} /* */
I guess since I've moved it to a separate class (they used to be the same one), I just want to make sure I'm calling th request/remove in the right place.
I haven't looked at your code in detail, but from what I've seen it looks fine to me. onResume() is the right place to register your listener, and onPause() is the right place to unregister it, so that e.g. battery life is optimised.
A couple of things to consider going forward:For a robust app, make sure you pay attention to the information that you get from onStatusChanged, onProviderEnabled and onProviderDisabled. I've seen various questions on stackoverflow.com to which the answer was to pay attention to status changes etc.Also for a better estimate of location, you might consider using the Location.accuracy value, because the accuracy of GPS location estimates can change. One minute they might be very accurate, but then the visible satellites change and the accuracy can suddenly be much lower. In my apps I use a simple Kalman filter for this, and I posted the code for it in my answer to the question Smooth GPS data.

Cannot fetch Location using google maps

I am trying to find my current location for an android project. When the application is loaded my current location is always null. I have set up the permissions in the manifest etc. When I find the current location I intend to use the coordinates to find distances to other locations on the map. My code snippet is below. Why do i always get a null value?
Here is my code:-
package com.example.location;
import android.content.Context;
import android.location.LocationManager;
import android.os.Bundle;
import android.location.Location;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapView;
import android.location.LocationListener;
import com.google.android.maps.MapController;
import android.widget.Toast;
import com.google.android.maps.GeoPoint;
public class MainActivity extends MapActivity implements LocationListener {
private MapView mapView;
private LocationManager locManager;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//fetch the map view from the layout
MapView mapView = (MapView) findViewById(R.id.mapview);
//make available zoom controls
mapView.setBuiltInZoomControls(true);
//latitude and longitude of Rome
double lat = 33.6667;
double lon = 73.1667;
//create geo point
GeoPoint point = new GeoPoint((int)(lat * 1E6), (int)(lon *1E6));
//get the MapController object
MapController controller = mapView.getController();
//animate to the desired point
controller.animateTo(point);
//set the map zoom to 13
// zoom 1 is top world view
controller.setZoom(13);
// invalidate the map in order to show changes
**mapView.invalidate();
// Use the location manager through GPS
locManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0,
0, this);
//get the current location (last known location) from the location manager
Location location = locManager
.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (location != null) {
Toast.makeText(
this,
"Current location:\nLatitude: " + location.getLatitude()
+ "\n" + "Longitude: " + location.getLongitude(),
Toast.LENGTH_LONG).show(); }
else {
Toast.makeText(this, "Cannot fetch current location!",
Toast.LENGTH_LONG).show();
}**
//when the current location is found – stop listening for updates (preserves battery)
locManager.removeUpdates(this);
}
#Override
protected boolean isRouteDisplayed() {
return false;
}
#Override
protected void onPause() {
super.onPause();
locManager.removeUpdates(this); //activity pauses => stop listening for updates
}
#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) {
}
}
Look at this example. very good example for doing things like you want.
http://mobile.tutsplus.com/tutorials/android/android-sdk-build-a-mall-finder-app-points-of-interest/

Categories

Resources