I'm building a location based app, everything was fine until one day I stopped receiving locations.. I have no idea why. I will attach the important code:
private LocationManager mLocationManager;
public void onCreate()
{
super.onCreate();
...
// Get a reference to the LocationManager object.
mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
...
setup();
}
private void setup()
{
mLocationManager.removeUpdates(listener);
// Request updates from just the providers.
if (mLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER))
mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, ONE_MINUTE, 0, listener);
if (mLocationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER))
mLocationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, ONE_MINUTE, 0, listener);
}
#Override
public void onLocationChanged(Location location)
{
handleLocation(location);
}
I put a break point on the onLocationChanged and nothing happened.. I tested it on other lines of my app to make sure that the debugging configuration is working and it is working. Looks like I just don't receive any locations.
Maybe I'm not seeing something.
I've good code to receive location :
public class Locato extends Activity implements LocationListener {
LocationManager locman;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.idlayout);
locman = (LocatonManager) getSystemService(Context.LOCATION_SERVICE);
}
public void onStatusChanged(String pr, int s, Bundle a) {
}
#Override public void onProviderDisabled(String provider)
{
Log.d("MyApp", "Provider disabled : " + provider);
}
#Override public void onProviderEnabled(String provider) {
Log.d("MyApp", "Provider enabled : " + provider);
}
#Override public void onLocationChanged(Location location) {
// do something
}
}
Try to use this.
Don't forget add ACCESS_FINE_LOCATION permission in manifest.
The same code now generates locations, it was kind of a joke when I said that it could be since it's cloudy but now when the clouds are gone it's working. I can't think about anything else and just to clarify it was very cloudy maybe even a small storm.
Related
Perhaps I am misunderstanding, but all the articles i've found for locationmanager and locationlistener in android refer to the onLocationChanged() method.
I want to get the current position of the user, not when it's changed. Am I using the right method? The locationchanged listener is working, and in the emulator runs the method when I change the location.
My app workflow is this:
-> App gets request from server for location
-> locationservice starts and stays on for 5 seconds to get the location
-> locationservice saves the location to preferences
-> locationservice stops
-> messaging service sends location to server
is a location listener the right method? will it still work if the user does not change location?
here's my location service:
public class MyLocationService extends Service {
public LocationManager locationManager;
public LocationListener mLocationListener;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#SuppressLint("MissingPermission")
public int onStartCommand(Intent intent, int flags, int startId){
locationManager = (LocationManager)getSystemService(LOCATION_SERVICE);
mLocationListener = new LocationListener() {
#Override
public void onLocationChanged(Location location) {
SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(MyLocationService.this).edit();
editor.putString("latitude", Double.toString(location.getLatitude()));
editor.putString("longitude", Double.toString(location.getLongitude()));
editor.commit();
System.out.println("Location got changed");
}
#Override
public void onStatusChanged(String s, int i, Bundle bundle) {
}
#Override
public void onProviderEnabled(String s) {
}
#Override
public void onProviderDisabled(String s) {
}
};
try {
locationManager.requestLocationUpdates(locationManager.getBestProvider(new Criteria(), true), 10000, 0, mLocationListener);
} catch (Exception e){
e.printStackTrace();
}
return START_STICKY;
}
}
but the location change is only registering when I do it as the service is open. How can I run that every time the service runs?
You will get the user's current position the first time LocationManager triggers LocationListener::onLocationChanged.
If you are interested only in the current location you can set up the LocationListener to receive the first location update and then stop.
public void onLocationChanged(Location location) {
// location gotten... store it somewhere
// and stop the location manager
locationManager.removeUpdates(this.locationListener);
}
Still, LocationListener::onLocationChanged will trigger depending on the criteria you have set to your LocationManager.
For instance:
this.locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this.locationListener);
will not be limited by any criteria, it will continuously request location updates.
is a location listener the right method? will it still work if the user does not change location?
Yes
I am developing an app related to Google map. I have done following steps successfully.
Created API key to access Google Map
Added Google Play Services Library in my app
Added required permissions
Added map in my activity with SupportMapFragment
Added a separate class MyMap.java to manipulate the map
Passed tow parameters to this class - Context of main activity and object of GoogleMap
Turned Wi-Fi and GPS on and ran the app
After this I am getting map with nice look and controls.
MyMap.java
public class MyMap implements ConnectionCallbacks, OnConnectionFailedListener {
private Context context;
private GoogleMap map;
private GoogleApiClient client = null;
public MyMap(Context context, GoogleMap map) {
this.context = context;
this.map = map;
client = new GoogleApiClient.Builder(context)
.addApi(LocationServices.API).addConnectionCallbacks(this)
.addOnConnectionFailedListener(this).build();
}
#Override
public void onConnectionFailed(ConnectionResult arg0) {
// TODO Auto-generated method stub
}
#Override
public void onConnected(Bundle arg0) {
Toast.makeText(context, "Connected", 1).show();
Location mLastLocation = LocationServices.FusedLocationApi
.getLastLocation(client);
if (mLastLocation != null) {
Toast.makeText(
context,
String.valueOf(mLastLocation.getLatitude()) + ","
+ String.valueOf(mLastLocation.getLongitude()), 1)
.show();
}
}
#Override
public void onConnectionSuspended(int arg0) {
// TODO Auto-generated method stub
}
}
Problem
In the above class I want to toast the current location. But it is not toasting anything. At least I need to see a toast saying "connected" on onConnected
event. Is there something wrong in my implementation?
Thanks in advance.
You seemingly never connect your client so it would be a real suprise if onConnected was called :)
You create your client with
client = new GoogleApiClient.Builder(context)
.addApi(LocationServices.API).addConnectionCallbacks(this)
.addOnConnectionFailedListener(this).build();
but for the client to do something you have to add:
client.connect();
getLastLocation() is going to give location only once. To get periodic location updates, you need to override onLocationChanged() method. You can get this Link
Best way that I found is simple implement you activity like so:
public class MapActivity extends Activity implements GoogleMap.OnMyLocationChangeListener
and override method
#Override
public void onMyLocationChange(Location location) {
mMap.addMarker(new MarkerOptions().position(location).icon(
BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN)));
}
And don't forget about mMap.setMyLocationEnabled(true); and mMap.setOnMyLocationChangeListener(this); in map init method
That's all!
Also, you can check is map available like here:
public boolean checkMapsAvailable() {
int isAvailable = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if (isAvailable == ConnectionResult.SUCCESS) {
return true;
} else if (GooglePlayServicesUtil.isUserRecoverableError(isAvailable)) {
Dialog dialog = GooglePlayServicesUtil.getErrorDialog(isAvailable, this, 9001);
dialog.show();
} else {
Constants.showToast(Constants.ALERT_GOOGLEPLAY_CONNECTION);
}
return false;
}
Hope this helps.
'm working on an android app, and i'm quite new to the android development.
At the moment i have problems to find a way to deactivate the GPS on the device.
What i'm trying to do is to deactivate the GPS when the user clicks a button. As far as i know the only way to do is buy using removeUpdates method from the LocationManager. But my problem is atm that this method awaits the LocationListiner as a parameter. But i don't know how to get the LocationListiner :/
Here is my code:
The following code is part of the onCreate of my MainActivity
Button save = (Button) findViewById(R.id.save);
save.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
// Startet die Abfrage der GPS Position
final LocationManager mLocMan = GetMyLocation();
final AlertDialog alertDialog = new AlertDialog.Builder(MainActivity.this).create(); //Read Update
alertDialog.setCanceledOnTouchOutside(false);
alertDialog.setTitle("GPS Signal");
alertDialog.setMessage("Some message");
alertDialog.setButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
mLocMan.removeUpdates();
}
});
alertDialog.show();
}
});
private LocationManager GetMyLocation(){
LocationManager locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
GetLocation getMyLocation = new GetLocation();
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, getMyLocation);
return locationManager;
}
Maybe someone has a hint for me. At the moment i have still some problems wrapping my head around the android system :/
You need to implement somewhere the LocationListener to be able of receive the updates via onLocationChanged(Location location).
And then, you juste have to locationManager.removeUpdates(MyLocationListener);
You can use the activity to implements the listener and then
locationManager.removeUpdates(this);
public class MyActivity extends Activity{
...
LocationManager manager;
GetLocation listener;
#Override
protected void onCreate() {
manager = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
listener = new GetLocation();
#Override
protected void onResume() {
manager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, listener);
}
#Override
protected void onPause() {
manager.removeUpdates(listener);
}
Currently i have the coding as below for use on my activity on android. Right now i use this as an object and start scanning location and get back it's location using returnBestLocation method 3seconds later using a handler.
However i would like to ask is there any possibility that MyLocationListener object will automatically return call the activity on location change instead of calling the object to retrtive location 3s later?
public class MyLocationListener implements LocationListener {
LocationManager locationManager;
Date currentBestLocationDate;
Intent notificationIntent;
Context mContext;
Location currentBestLocation = null, lastKnownLocation=null;
public MyLocationListener(Context mContext)
{this.mContext = mContext;
}
public void startLocationScan()
{
Log.d(Config.log_id, "Custom Location Listener started");
if (locationManager == null) {
locationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
Location locationNETWORK = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (locationNETWORK != null) {
lastKnownLocation=locationNETWORK;
}
Location locationGPS = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (locationGPS != null) {
lastKnownLocation=locationGPS;
}
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, MyLocationListener.this);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0,MyLocationListener.this);
}
}
public void stopLocationScan()
{
if(locationManager!=null)
{
locationManager.removeUpdates(MyLocationListener.this);
Log.d(Config.log_id, "Custom Location Listener Stopped");
}
}
public Location returnBestLocation()
{
return currentBestLocation;
}
#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 onLocationChanged(Location location) {
// TODO Auto-generated method stub
if (currentBestLocation == null) {
currentBestLocation = location;
}
long timeDelta = location.getTime() - currentBestLocation.getTime();
Log.d(Config.log_id, "locationpostingservice's changed with accuracy " + location.getAccuracy() + " s different " + (float) timeDelta / 1000);
if (timeDelta >= 120000) {
currentBestLocation = location;
Log.d(Config.log_id,"posting service Location changed due to over 2min "+ location.getAccuracy() + " s different "+ (float) timeDelta / 1000);
}
if (currentBestLocation.getAccuracy() >= location.getAccuracy()) {
currentBestLocation = location;
}
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
You could pass the Activity you want to be notified to MyLocationListener as a Listener. Create your own Listener interface, let the Activity implement it and add a method to MyLocationListener like addListener(). Every time you want to notify those activities iterate through the list of Listeners and call their locationChanged method (or whatever you called it in your interface definition). Just be sure to add error handling for null listener Activities, etc.
So basically you have your own custom Listeners listening to a LocationListener.
Another way would be to use Broadcast Receivers and broadcast the location change.
The proper way to do this is, as Fraggle says, to create your own listener interface, implement it in your class, then call your listener from your Activity.
But a quick-n-dirty alternative could be to just implement the LocationListener interface in your Activity, rather than spinning it off into a new class (MyLocationListener). Then just put all the code you want to run into onLocationChanged, and don't worry about communicating with other objects.
I've got a serious problem with my GPS on my Nexus One: I wrote a kind of hello world with GPS, but the Toast that should be displayed isn't :(
I don't know what I'm doing wrong...maybe you could help me getting this work. Here's my code:
package gps.test;
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.Toast;
public class GPS extends Activity {
private LocationManager lm;
private LocationListener locationListener;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// ---use the LocationManager class to obtain GPS locations---
lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationListener = new MyLocationListener();
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 100, 1,
locationListener);
}
private class MyLocationListener implements LocationListener {
#Override
public void onLocationChanged(Location loc) {
if (loc != null) {
Toast.makeText(
getBaseContext(),
"Location changed : Lat: " + loc.getLatitude()
+ " Lng: " + loc.getLongitude(),
Toast.LENGTH_SHORT).show();
}
}
#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
}
}
}
Theoretically there should be a new toast every 100 milliseconds, shouldn't it? Or at least, when I change my position by one meter!?
I've no idea why it doesn't. I must admit I'm new to the topic, maybe I've missed something?
It would be great if you could give me a hint :)
nice greetings,
poeschlorn
The code looks correct to me. Do note that:
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 100, 1,
locationListener);
This means that you will have to move the phone by more than a meter to get location updates and the check is done approximately every 0.1 second.
I would suggest you add logging statements in these functions:
#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
}
This is so that you know what flow your code is taking. GPS could be disabled for e.g. and you'll not know within your app.
And finally, do remember to remove listening to locations in onPause (or when required). Having an app in the background that is continuously getting location updates when not required is a huge drain to the battery.
Here are few steps I would follow:
Check if you have enabled GPS location services.
Check if you have GPS signal available (you can get some GPS monitor from market)
You can change the code to use best possible provider: D:/java-workspace/android-sdk-windows/docs/reference/android/location/LocationManager.html#getBestProvider(android.location.Criteria, boolean)
Try it in the emulator (you have to send location update from DDMS (Emulator Control)