I'm working on an Android project which give the user the possibility to turn on his GPS. His position is requested to launch the application.
After activation, I use getLastKnownLocation of LocationManager but this method returns a Location indicating the data from the last known location fix obtained from the given provider. The doc explains that this can be done without starting the provider. Note that this location could be out-of-date, for example if the device was turned off and moved to another location.
However the user activate localization services. So turn on the GPS is not enough to launch the GPS as it's done by Google Maps by showing an icon at the top of the device and retrieving GPS coordinates. This icon doesn't appear when my application gives the user the possibility to activate the GPS (seems weird).
Theards I already read use getLastKnownLocation method after choosing the best provider. Questions are did I miss something after turning on the GPS services? Did the GPS is automatically launch when the GPS is activated?
I already ask this, but not enough answer.
for showing blue dot icon on map use this line
map_fragment.setMyLocationEnabled(true);
use this code to get location where you want to get location
GPSTracker gps = new GPSTracker(this);
Double latiDouble = gps.getLatitude();
Double loDouble = gps.getLongitude();
create a class GPSTracker and add this code
public class GPSTracker extends Service implements LocationListener {
private final Context mContext;
boolean isGPSEnabled=false;
boolean isNetworkEnabled=false;
boolean canGetLocation=false;
Location location;
double latitude;
double longitude;
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
private 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);
isNetworkEnabled=locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if(!isGPSEnabled && !isNetworkEnabled)
{
//showSettingAlert();
}
else
{
this.canGetLocation=true;
if(isGPSEnabled)
{
if(location==null)
{
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES,this);
}
if(locationManager != null)
{
location=locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if(location != null)
{
latitude=location.getLatitude();
longitude=location.getLongitude();
}
}
}
if(isNetworkEnabled)
{
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES,this);
if(locationManager!=null)
{
location=locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if(location!=null)
{
latitude=location.getLatitude();
longitude=location.getLongitude();
}
}
}
}
return location;
}
public void stopUsingGPS()
{
if(locationManager!=null)
{
locationManager.removeUpdates(GPSTracker.this);
}
}
public double getLatitude()
{
if(location != null)
{
latitude=location.getLatitude();
}
return latitude;
}
public double getLongitude()
{
if(location != null)
{
longitude=location.getLongitude();
}
return longitude;
}
public boolean canGetLocation(){
return this.canGetLocation;
}
public void showSettingAlert()
{
AlertDialog.Builder alertDialog=new AlertDialog.Builder(mContext);
alertDialog.setTitle("GPS Settings");
alertDialog.setMessage("GPS is not enabled .Do you want to go to settings menu ?");
alertDialog.setPositiveButton("Settings",new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
Intent i=new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
mContext.startActivity(i);
}
});
alertDialog.setNegativeButton("Cancel",new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
dialog.cancel();
}
});
}
public void onLocationChanged(Location location) {
// TODO Auto-generated method stub
}
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
}
No, turning on GPS is not enough, you also need a Location Listener to listen to updates of position.
Something like in Location Strategies
// Acquire a reference to the system Location Manager
LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
// Define a listener that responds to location updates
LocationListener locationListener = new LocationListener() {
public void onLocationChanged(Location location) {
// Called when a new location is found by the network location provider.
makeUseOfNewLocation(location);
}
public void onStatusChanged(String provider, int status, Bundle extras) {}
public void onProviderEnabled(String provider) {}
public void onProviderDisabled(String provider) {}
};
// Register the listener with the Location Manager to receive location updates
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
Related
I want after open dialog and click on location button, detect user's location and show user's location and then user dismiss dialog, location listener removes and not get location from onLocationChanged, I try used locationManager.removeUpdate(locListener)on override dismiss but not any chance and location after dismiss again shows! why? How can i detect user's location after show dialog and after detect location, location listener remove? Thanks
EDIT:
public class DialogTest extends Dialog implements
android.view.View.OnClickListener {
Context context;
LocationManager locationManager;
LocationListener locationListener;
Location location;
public DialogTest(Context context) {
super(context);
// TODO Auto-generated constructor stub
requestWindowFeature(Window.FEATURE_NO_TITLE);
this.context = context;
setContentView(R.layout.profile_dialog);
getWindow().setBackgroundDrawableResource(R.drawable.background_dialog);
firstAccessLocation=true;
setCancelable(true);
initialize();
}
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
findAddress();
}
private void findAddress() {
// if (gpsCheckBox.isChecked()) {
locationManager = (LocationManager) context
.getSystemService(Context.LOCATION_SERVICE);
locationListener = new GPSLocationListener();
locationManager.requestLocationUpdates(locationManager.GPS_PROVIDER, 0,
0, locationListener);
locationManager.requestLocationUpdates(
locationManager.NETWORK_PROVIDER, 0, 0, locationListener);
// }
}
private void stopTracking(){
if(locationManager!=null){
locationManager.removeUpdates(locationListener);
}
}
#Override
public void dismiss() {
// TODO Auto-generated method stub
stopTracking();
gpsTurnOff();
super.dismiss();
}
public class GPSLocationListener implements LocationListener {
#Override
public void onLocationChanged(Location loc) {
// TODO Auto-generated method stub
if(location!=null)
Log.e("location", location.getLatitude()+"");
location = loc;
if (location != null&& firstAccessLocation) {
setAddress(location.getLatitude(), location.getLongitude());
firstAccessLocation=false;
}
Toast.makeText(context, "changed", Toast.LENGTH_LONG).show();
Log.e("location", "changed");
}
#Override
public void onProviderDisabled(String arg0) {
// TODO Auto-generated method stub
}
#Override
public void onProviderEnabled(String arg0) {
// TODO Auto-generated method stub
}
#Override
public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
// TODO Auto-generated method stub
}
}
}
In new code you should use LocationClient rather then LocationManager. It's more efficient in getting the location with minimal energy(battery drain) with greater accuracy. Look here LocationClient vs LocationManager. With LocationClient established you can call getLastLocation() which provide you last location and doesn't start cyclic location updates.
If you want to stick with LocationManager use requestSingleUpdate (String provider, LocationListener listener, Looper looper) method to get only one newest location from it.
Hie i tried to implement this codes in my application but it doesnt work , i dont know where i went wrong.
basically, when i launch the sample of the device location. it doesnt show me where is my current location and i dont see any blue dots that resembles the current location i am at.
the only thing that i see is the map . just a plain zoom out map.
I would be really thankful if someone who could help me out on how to get the current location with the blue dots that is displayed on the map..
this is my MainActivity.class
public class HelloWorld extends Activity {
MapView mMapView = null;
ArcGISTiledMapServiceLayer tileLayer;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Retrieve the map and initial extent from XML layout
mMapView = (MapView) findViewById(R.id.map);
mMapView.addLayer(new ArcGISTiledMapServiceLayer(
"http://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer"));
mMapView.setOnStatusChangedListener(new OnStatusChangedListener() {
public void onStatusChanged(Object source, STATUS status) {
if (source == mMapView && status == STATUS.INITIALIZED) {
LocationService ls = mMapView.getLocationService();
ls.setAutoPan(false);
ls.start();
}
}
});
}
protected void onPause() {
super.onPause();
mMapView.pause();
}
#Override
protected void onResume() {
super.onResume();
mMapView.unpause();
}
}
this is a code that draws my location every 1 second via provider and GPS .
let's first declare variables :
private GraphicsLayer myGraphicalLayer;
MapView mMapView;
ArcGISLocalTiledLayer baseLayer;
private LocationManager mlocManager;
private LocationListener mlocListener;
in onCreate function WE CALL LocationListener:
mlocManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
mlocListener = new MyLocationListener();
mlocManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 0, mlocListener);
mlocManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1000, 0, mlocListener);
// loading the map
mMapView = (MapView) findViewById(R.id.localMap);
baseLayer = new ArcGISLocalTiledLayer(basemapurl);
mMapView.addLayer(baseLayer);
// defining my position layer
myGraphicalLayer = new GraphicsLayer();
then a function to draw my location :
private void SetMyLocationPoint(final double x, final double y) {
PictureMarkerSymbol myPin = new PictureMarkerSymbol(getResources().getDrawable(
R.drawable.mylocation_icon));
Point wgspoint = new Point(x, y);
Point mapPoint = (Point) GeometryEngine.project(wgspoint, SpatialReference.create(4326),
mMapView.getSpatialReference());
Graphic myPinGraphic = new Graphic(mapPoint, myPin);
try {
myGraphicalLayer.removeAll();
} catch (Exception e) {
e.printStackTrace();
}
myGraphicalLayer.addGraphic(myPinGraphic);
myGraphicalLayer.setVisible(true);
mMapView.addLayer(myGraphicalLayer);
}
make internal class that implements MyLocationListener to get you instant location, and let it call the function named SetMyLocationPoint like this way :
public class MyLocationListener implements LocationListener {
#Override
public void onLocationChanged(Location loc) {
SetMyLocationPoint(loc.getLongitude(), loc.getLatitude());
}
#Override
public void onProviderDisabled(String provider) {
Toast.makeText(getApplicationContext(), "provider enabled", Toast.LENGTH_SHORT)
.show();
}
#Override
public void onProviderEnabled(String provider) {
Toast.makeText(getApplicationContext(), "provider disabled", Toast.LENGTH_SHORT)
.show();
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
}
You need to use your own location manager or the location client to get the device's current location and then you will have to add that point on the map.
Your map should be in a MapFragment.
Get the googleMap object from the fragment and then add your custom blue dot on it.
LocationManager locationManager = (LocationManager) getApplicationContext()
.getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
5000, 5, listener);
}
private LocationListener listener = new LocationListener() {
#Override
public void onLocationChanged(Location location) {
// TODO Auto-generated method stub
Log.e("Google", "Location Changed");
if (location == null)
return;
Log.e("latitude", location.getLatitude() + "");
Log.e("longitude", location.getLongitude() + "");
}
}
#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
}
};
The above code gets you the location in onLocationChanged method.
Note: i have used GPS_PROVIDER to get the location.
There are other ways to get the current location too.
I using the new API for get location: android.https://developer.android.com/training/location/retrieve-current.html
Some times when I get the location, It come out of date. I get out at some place and go to another place, then the application returns the first place location to me. It happens when I out the WiFi. When I use the WiFi it works perfectly. Am I missing some method or something else?
public class NewGPSTracker implements
GooglePlayServicesClient.ConnectionCallbacks,
GooglePlayServicesClient.OnConnectionFailedListener,
LocationListener, com.google.android.gms.location.LocationListener {
private LocationRequest lr;
private LocationClient lc;
Location location;
double latitude = 0;
double longitude = 0;
Context context;
static Boolean status = false;
public int res = 0;
boolean conectado;
public NewGPSTracker(Context context) {
this.context = context;
lr = LocationRequest.create();
lr.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
lr.setInterval(5000);
lr.setFastestInterval(1000);
lc = new LocationClient(context, this, this);
}
#Override
public void onLocationChanged(Location location) {
if (conectado) {
lc.removeLocationUpdates(this);
lc.requestLocationUpdates(lr, this);
location = lc.getLastLocation();
if(location != null){
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
#Override
public void onConnectionFailed(ConnectionResult arg0) {
Log.e("NewGPSTracker", ""+arg0);
}
#Override
public void onConnected(Bundle connectionHint) {
conectado = true;
Log.i("NewGPSTracker", "Google Play Services Conectado.");
lc.requestLocationUpdates(lr, this);
location = lc.getLastLocation();
if(location != null){
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
public double getLatitude() {
return latitude;
}
public double getLongitude() {
return longitude;
}
public void connect(){
lc.connect();
}
public void disconnect(){
lc.disconnect();
}
#Override
public void onDisconnected() {
}
public void onProviderDisabled(String arg0) {
// TODO Auto-generated method stub
}
public void onProviderEnabled(String arg0) {
// TODO Auto-generated method stub
}
public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
// TODO Auto-generated method stub
}
}
lr.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
I exactly don't know what are you using. But when i use google API for this situation, solved a issue like that.
Now line that at top always uses HIGH_ACCURACY of GPS/WI-FI. And your situation it looks like WI-FI always.. As you know there are two method to find user's location. (GPS/WI-FI) when you change your GPS location and not opening your WI-FI it should keep showing first.
So try to change it as a static variable like GPS, if it's possible.
Sorry for my bad english, complicated situation..
Calculate the difference of the time stamp of the location to the current time.
If it is more than some seconds, it is an old positoin, e.g the last known.
In that case wait for the next position, untill time difference is less than some seconds.
I use the following code to get Current Location from a Network provider in my application:
LocationManager mgr = (LocationManager) getSystemService(LOCATION_SERVICE);
boolean network_enabled = mgr.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if(network_enabled){
Location location = mgr.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
But it gives a location approximately 300-700 meters away from my actual location.
This is expected from a Network provider. But the problem is:
with only this Network provider enabled, and no GPS, I openned Foursquare
application where it shows my current location exactly where I am. Now
when I come back to my application, it shows the accurate current
location or say the same location which Foursquare showed.
Same thing happens with Google apps like Navigator, Maps etc..,
How can this be done? How are other apps able to get the exact location, based on just the Network provider?
Complete Code:
public class MyLocationActivity extends Activity implements LocationListener {
private LocationManager mgr;
private String best;
Location location;
public static double myLocationLatitude;
public static double myLocationLongitude;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mgr = (LocationManager) getSystemService(LOCATION_SERVICE);
Criteria criteria = new Criteria();
best = mgr.getBestProvider(criteria, true);
location = mgr.getLastKnownLocation(LocationManager.GPS_PROVIDER);
dumpLocation(location);
}
public void onLocationChanged(Location location) {
dumpLocation(location);
}
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
#Override
protected void onPause() {
super.onPause();
mgr.removeUpdates(this);
}
#Override
protected void onResume() {
super.onResume();
mgr.requestLocationUpdates(best, 15000, 10, this);
}
private void dumpLocation(Location l) {
if (l != null){
myLocationLatitude = l.getLatitude();
myLocationLongitude = l.getLongitude();
}
}
}
Thank You
You are getting just the last known location. You should request location updates from the LocationManager. Use LocationManager.getLocationUpdates.
On your LocationListener on the onLocationChanged(Location location) method, you can check on the Location object, how accurate this location is, like this :
float accuracy=location.getAccuracy();
then, if this Location is accurate enough for you, you can stop receiving location updates from the LocationManager using removeUpdates() , and use the received Location. If the Location is not accurate enough, you can wait for a more precise Location, and stop the updates latter on.
i'm new in java/android app and i'm creating an app that uses user-location. I want the location to be updated at the begining of the app.
The problem is that my location class is an activity and i don't want to show another contentview for this class.
Actually, i want the location thing to be done in background, without changing the UI, in a separated class.
Is it possible? How?
Thanks :P
There is no need to put the location in a different activity, the LocationManager already does it in the background:
public void getLocation(){
lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
gpsLocationListener = new LocationListener() {
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
#Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onLocationChanged(Location location) {
//do something with the new location
if (location != null)
gpsLocation = location;
}
};
gpsLocation = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1, 0, gpsLocationListener);
}
Using the LocationManager you should be able to use what ever kind of activity (or service) you want.