LocationListener is never called - android

I have a client-server application where the client sends a "ping" and the server responds back with a "pong". On receipt of the "pong", the client sends its location updates (GPS data) to the server. On receiving the location updates, the server sends a "pong" and this goes on for a while.
The sockets (for sending and receiving messages) are created by the client and server in separate threads. I register the LocationListener in the main thread. The problem is that, I do not get any updates from the GPS. I checked the GPS by running a separate app that displays the number of satellites seen and the time taken for the first fix. It took about 90 seconds for the first fix.
The problem I have is very similar to the ones mentioned here and here. Also here.
My code is given below:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationManager.getBestProvider(criteria, true);
isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
if (!isGPSEnabled) {
Log.i(TAG,"PING: GPS not enabled");
} else {
Log.i(TAG,"PING: GPS enabled");
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locListener);
Log.i(TAG,"PING: adding GPS status listener");
locationManager.addGpsStatusListener(PingActivity.this);
}
/*The server and client threads are started after this.*/
The LocationListener is as follows:
LocationListener locListener = new LocationListener()
{
#Override
public void onLocationChanged(Location location) {
Log.i(TAG, "PING: onLocationChanged");
Log.i(TAG, "PING: location is " + location.getLatitude() + ", " + location.getLongitude());
}
As you can see, there are just two log statements in the LocationListener and these two log statements are not printed at all. Is it because I have a thread constantly listening for updates and the LocationListener is never invoked? I also tried creating a separate activity for the GPS and registering that before starting the client-server threads.
These are the permissions in the manifest file.
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET"/>
The message I get in LogCat is
duplicate add listener for uid
Can someone throw some light on this? Thanks.

You getting error for the code (extract from android source)
private void handleAddListener(int uid) {
synchronized(mListeners) {
if (mClientUids.indexOfKey(uid) >= 0) {
// Shouldn't be here -- already have this uid.
Log.w(TAG, "Duplicate add listener for uid " + uid);
return;
}
mClientUids.put(uid, 0);
if (mNavigating) {
try {
mBatteryStats.noteStartGps(uid);
} catch (RemoteException e) {
Log.w(TAG, "RemoteException in addListener");
}
}
}
}
mClientUids is declared as
private final SparseIntArray mClientUids = new SparseIntArray();
And, in your code,
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locListener);
locationManager.addGpsStatusListener(PingActivity.this);
In here you are adding two different listener and that is what Android is complaining about.

Related

Android unable to get current location using GPS when device is not moving

I want to get current latitude and longitude of device even when it is not in movement.
Tried both requestLocationUpdates() and requestSingleUpdate() but my location is still null. LocationManager.onLocationChanged() seems to be called only when location gets changed. I want to post this location details but fails with NullPointerException every time.
Here are my code samples:
Activity:
startButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, myLocationListener);
if (location == null) {
try {
locationManager.requestSingleUpdate(LocationManager.GPS_PROVIDER, myLocationListener, Looper.myLooper());
} catch (SecurityException e) {
}
}
//MyLocationListener
public void onLocationChanged(Location location) {
activity.setLocation(location);
}
}
}
Manifest:
<uses-permission android:name="android.permission.ACCESS_GPS" />
<uses-permission android:name="android.permission.ACCESS_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
If the user has not used GPS for a while, there will be no last known location, hence the GPS provider will not update at all unless you move outside. Its better to use the new FusedLocationApi to get updates as it selects the best source for you and gives you the best possible location.
https://developer.android.com/training/location/receive-location-updates.html
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
Trying putting your code in AsyncTask.

How to find the GPS and Network provider status without consuming GPS?

How to listen for GPS and Network Provider status without consuming the GPS.
I want to know the status alone. I dont want to get the location information.
I have used the below code,
mLocationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER, 0, 0, this);
mLocationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER, 0, 0, this);
mLocationManager.requestLocationUpdates(
LocationManager.PASSIVE_PROVIDER, 0, 0, this);
When using the above code, the GPS icon is always splashing in the notification bar. It means that it is always consuming the GPS. I don't want the GPS to be consumed just to check the GPS status. Because this is draining the battery power.
Checking the GPS ON or OFF is different from consuming the GPS.
And also I have explored and found the way to check the GPS status alone
"GpsStatus.Listener".
But I want to know both the GPS and Network provider status. I don't want the location information.
Please help me on this.
Find my answer below,
Registered local broadcast receiver to update the UI whenever the location provider status changes,
getApplicationContext().registerReceiver(mGpsNetworkStatusChangeReceiver,
new IntentFilter(LocationManager.PROVIDERS_CHANGED_ACTION));
Below is my Broadcast receiver:
public class GpsNetworkStatusReceiver extends BroadcastReceiver {
private static final String TAG = GpsNetworkStatusReceiver.class
.getSimpleName();
private AppUtil mAppUtilInstance = AppUtil.getInstance();
#Override
public void onReceive(Context context, Intent intent) {
mAppUtilInstance.logDebugMessage(TAG,
"GpsNetworkStatusReceiver - onReceive");
mLocationManager = (LocationManager) mContext
.getSystemService(Context.LOCATION_SERVICE);
//check the GPS and NEtwork Provider Status and update the UI
boolean gpsEnabled = mLocationManager
.isProviderEnabled(LocationManager.GPS_PROVIDER);
boolean networkEnabled = mLocationManager
.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
}
}

Android- same GPS location repeating without updating

I have tried to do my research about GPS issues before posting here. When I tested my code It repeats the same output over and over. The method gpsStart() is called on a timer. Fine and Coarse location permissions have been added to the manifest. The method appendLog() stores the output in a file.
public void gpsStart() {
// 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) {
// Toast.makeText(getApplicationContext(), "location changed",
// Toast.LENGTH_SHORT).show();
// Called when a new location is found by the network location
// provider.
appendLog("Lat: " + location.getLatitude() + "\nLng: "
+ location.getLongitude()+"\n");
text3.setText("Lat: " + location.getLatitude() + "\nLng: "
+ location.getLongitude());
}
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);
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);
}
You must not call gpsStart() method in the timer. I am going to say how Location Listener works
What is Location Listener?
Location Listener is the class which notify you when your current location will be change. For receive the location updates you will have to register LocationListener class using LocationManager class.
When to register Location Listener?
It depends on the requirement of your application. For example if you want location listener for display current location on map then you should register Location Listener in onCreate() or onResume() method of the activity and unregister receiver in onPause() or onStop() method. If you want to receive the location even if your application is not running then you can use a service to receive location.
How to Register/Unregister Location Listener?
To register the LocationListener you first need the instance of the LocationManager class which you can get using the context like
LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
After then you will have to set the location provider. There are 2 types of providers which are often used.
GPS provider
Network Provider
Now to register the location receiver with this location provider there is a method requestLocationUpdates of LocationManager. In this method first argument is the provider name second argument is the minimum time for request location update. Third argument is the minimum distance to request for the location change.Last argument is for locationListener.
Here how you can use the method
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER, minTime, minDistance, locationListener);
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER, minTime, minDistance, locationListener);
To unRegister location updates you can use the below method
locationManager.removeUpdates(locationListener)
Note: You are calling a method gpsStart in the timer as you have mentioned in your question so it is adding location listener each time when this method calls.So all the listeners are triggering you the new location so probably you are getting same location multiple times. Instead of it, you should call this method once when your activity starts and unRegister this locationListener when your activity finish.
Hopes you are getting. :D
Enjoy!!!
Better you create a 2 listeners.1 for Gps and other for network.
the following are code samples
public class MyLocationListener extends LocationListener
{
public void onLocationChanged(Location location)
{
// Toast.makeText(getApplicationContext(), "location changed",
// Toast.LENGTH_SHORT).show();
// Called when a new location is found by the network location
// provider.
appendLog("Lat: " + location.getLatitude() + "\nLng: "
+ location.getLongitude()+"\n");
text3.setText("Lat: " + location.getLatitude() + "\nLng: "
+ location.getLongitude());
}
public void onStatusChanged(String provider, int status,
Bundle extras) {
}
public void onProviderEnabled(String provider) {
}
public void onProviderDisabled(String provider) {
}
}
MyLocationListener gpsListener=new MyLocationListener();
MyLocationListener networkListener=new MyLocationListener();
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, gpslocationListener); locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, networklocationListener);
Thank you very much for your answers. Dharmendra you are correct, I did need to close the LocationListeners, however the answer to my question was much simpler. I needed to change the minimum time (the time the listener waits to get an answer) to a value above zero. The value I needed to change is shown in bold below (MINTIME).
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, MINTIME, 0, gpslocationListener); locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, MINTIME, 0, networklocationListener);

android getLaskKnownLocation null

I have tried both GPS and Network Provider but they give null location for getLastKnownLocation. I do not get any onLocationChanged either. I am trying from my apartment where the cell signal is strong. I can even browse internet well and download and install apps fine from market.
I have read few threads on same topic but their suggestion seems I already have tried.
Here is my code snippet.
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
if(null == locationManager) {
Log.d(TAG, "location manager NULL");
}
geocoder = new Geocoder(this);
// Initialize with the last known location
Location lastLocation = locationManager
.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (lastLocation != null)
onLocationChanged(lastLocation);
else
Log.i(TAG, "null LastKnownLocation");
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
super.onStartCommand(intent, flags, startId);
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,
0,0, this);
Log.d(TAG, "requested location updates");
return START_STICKY;
}
As per log:
mitenm#pinkydebian:/media/sf_E_DRIVE/tmp$ adb logcat LocationNotifierService:* *:S
--------- beginning of /dev/log/system
--------- beginning of /dev/log/main
I/LocationNotifierService(30866): null LastKnownLocation
D/LocationNotifierService(30866): gps provider enabled:true
D/LocationNotifierService(30866): network provider enabled:true
D/LocationNotifierService(30866): onCreate
D/LocationNotifierService(30866): requested location updates
D/LocationNotifierService(30866): requested location updates
D/LocationNotifierService(30866): requested location updates
I have "unlock receiver" so when I unlock my screen I request location updates which is working as expected from logs. But the onLocationChanged method is not getting invoked.
I have permission added to manifest both for fine and coarse.
Regards,
Miten.
android getLaskKnownLocation null
As Per Google Doc
getLaskKnownLocation Returns a Location indicating the data from the last known location fix obtained from the given provider otherwise it returns null.
It means it shows the cached data.If you are running your application on device which has never queried for location data before will have empty cache thats why you are getting null.
do not get any onLocationChanged either.
Make sure you have enabled Network Provider for location.
Use below Snippet.
if (connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).isConnected() || connectivityManager.getNetworkInfo(
ConnectivityManager.TYPE_WIFI).isConnected()) {
if (locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
Constants.CONNECTED = true;
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER, 5000, 1, this);
} else {
Constants.CONNECTED = false;
Toast.makeText(
context, "Please enable Wireless networks in Location Setting!!", 10000).show();
}
}

wifi provider onLocationChanged is never called

I got a weird problem. I uses wifi to retrieve user location. I have tested on several phones; on some of them, I could never get a location update. it seemed that the method onLocationChanged is never called. My code is attached below.. Any suggestions appreciated!!!
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
LocationManager locationManager;
locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
String provider = locationManager.NETWORK_PROVIDER;
Location l = locationManager.getLastKnownLocation(provider);
updateWithNewLocation(l);
locationManager.requestLocationUpdates(provider, 0, 0,
locationListener);
}
private void updateWithNewLocation(Location location) {
TextView myLocationText;
myLocationText = (TextView)findViewById(R.id.myLocationText);
String latLongString = "No location found";
if (location != null) {
double lat = location.getLatitude();
double lng = location.getLongitude();
latLongString = "Lat:" + lat + "\nLong:" + lng;
}
myLocationText.setText("Your Current Position is:\n" +
latLongString);
}
private final LocationListener locationListener = new LocationListener() {
public void onLocationChanged(Location location) {
updateWithNewLocation(location);
Log.i("onLocationChanged", "onLocationChanged");
Toast.makeText(getApplicationContext(), "location changed",
Toast.LENGTH_SHORT).show();
}
public void onProviderDisabled(String provider) {}
public void onProviderEnabled(String provider) {}
public void onStatusChanged(String provider, int status,
Bundle extras) {}
};
Manifest
<uses-permission
android:name="android.permission.ACCESS_FINE_LOCATION"
/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
My guess is that the phones on which you don't get location updates from do not have proper data connection. Network Provider needs GSM/3G or WiFi data connection to retrieve a location fix from Google servers using phones's cell/wifi data. You can use the method below to check this.
public boolean isOnline() {
ConnectivityManager cm =
(ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
if (netInfo != null && netInfo.isConnectedOrConnecting()) {
return true;
}
return false;
}
Please check that your onProviderDisabled method is not being called immediately.
If you find it is being called as soon as your provider registers, it means that the phone you're on has location services disabled.
It's my suspicion now that Google Location Services were down in select areas. My app started working again with no changes to the code (the apk from the Play Store).
I too faced the same issue with NetworkProvider while testing in ICS(4.0) but working fine in older versions(2.2 and 2.3.3 i tested). Here is the solution i found and working fine in ICS as well. Please use the Criteria for getting the location updates as below:
LocationManager locationManager= (LocationManager) <YourAct>
.getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_COARSE); //ACCURACY_COARSE or ACCURACY_FINE based on usage
String provider = locationManager.getBestProvider(criteria, true);
// Register the listener with the Location Manager to receive location
// updates
locationManager.requestLocationUpdates(provider, 0, 0, locationListener);
Replace the code as above. This will help u in getting the location updates.
I had the very same problem and in turns out that onLocationChanged is not called if there is getLastKnownLocation which is the same as "current". That means that you will not get new location because there is nothing new to report...
Solution is to use the last known location even it is very old (and continue to listen for updates if you need more precise/new location (if such occurres)).

Categories

Resources