wifi provider onLocationChanged is never called - android

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)).

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.

Android Device Location from Ethernet

I've a TI OMAP platform running Kitkat 4.4.4. The platform doesn't have Wifi/GPS/Cellular connection but it has ethernet. I use eth1 to access internet.
Is there anyway to determine the coarse geographical location of the device based on eth1. I tried the sample code below, but it fails for ethernet connection.
/** Check if we can get our location */
public void checkLocation(){
// Get the location manager
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
String locationProvider = LocationManager.NETWORK_PROVIDER;
try{
// Define a listener that responds to location updates
locationListener = new LocationListener() {
public void onLocationChanged(Location location) {
Log.d(TAG,"Latitude: " + location.getLatitude() + ", Longitude = " + location.getLongitude());
}
public void onStatusChanged(String provider, int status, Bundle extras) {Log.d(TAG,"location found 1");}
public void onProviderEnabled(String provider) {Log.d(TAG,"location found 2");}
public void onProviderDisabled(String provider) {Log.d(TAG,"location found 3");}
};
locationManager.requestLocationUpdates(locationProvider, 0, 0, locationListener);
}catch(Exception e){
Log.e(TAG, "Location Exception: " + e.getMessage());
}
}
Above code throws provider doesn't exist: network exception for ethernet. Works OK on a device with wifi/GPS.
I've also set the following permissions in manifest file.
<uses-permission android:name="android.permission.INTERNET" />
<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" />
Any ideas how to determine location if the device has on ethernet connectivity?
Thanks
You can use
locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)
and
locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)
to check the availability of your network or gps. If these two return false to you, then you might not be able to use the locationManager to find location.

Getting 0.0 for longitude and latitude on tablet

I am getting longitude=0.0 and latitude=0.0 on tablet while this is working perfectly on the phone.
I am using LocationManager.NETWORK_PROVIDER and not the GPS_PROVIDER so what could be the cause please?
Logcat output??
that's my code:
// Acquire a reference to the system Location Manager
locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
// Define a listener that responds to location updates
locationListener = new LocationListener() {
public void onLocationChanged(Location location) {
// Called when a new location is found by the network location provider.
longitude=location.getLongitude();
latitude=location.getLatitude();
}
public void onStatusChanged(String provider, int status, Bundle extras) {}
public void onProviderEnabled(String provider) {}
public void onProviderDisabled(String provider) {}
};
//Or use LocationManager.GPS_PROVIDER
String locationProvider = LocationManager.NETWORK_PROVIDER;
// Register the listener with the Location Manager to receive location updates
locationManager.requestLocationUpdates(locationProvider, 0, 0, locationListener);
Location lastKnownLocation = locationManager.getLastKnownLocation(locationProvider);
if(lastKnownLocation!=null){
longitude=lastKnownLocation.getLongitude();
latitude=lastKnownLocation.getLatitude();
}
Check out Location settings inside your device settings. This seems not a problem with your code, but your device settings. In my Ginger bread, it's as:
Settings -> Location&security -> Use wireless networks

LocationListener is never called

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.

finding current location in android through GPS

Is there possible to get accurate latitude and longitude of a user through "GPS" after changing its location of very shorter distance like 3-4 feet.
Actually I have made an application in android which gives me latitude and longitude of a user but, it changes its value on a same point or location of a user.
Kindly help me out of this problem.
thanks in advance.
My Experience says It depends on Phone/Device you are using, if your device support AGPS then getting GPS coordinates will be easier and fast (No related to your coding skill as you will be using android SDK). Normal GPS also return accurate data, try downloading Savaari application from google play, It works like charm, your 2nd Question Yes it is possible to get coordinates after a specific time or distance interval, when ever you are registering your listner you have to provide time and distance (in Meters) after which you want to receive GPS Value.
Check out this snippet : -
public void startReadingGPS(int readAfterMinimumTime, int readAfterMinimumDistance ){
locationManager = (LocationManager)mContext.getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, readAfterMinimumTime, readAfterMinimumDistance, this);
}
public void requestLocationUpdates (String provider, long minTime, float minDistance, LocationListener listener)
Added in API level 1
Register for location updates using the named provider, and a pending intent.
See requestLocationUpdates(long, float, Criteria, PendingIntent) for more detail on how to use this method.
Parameters
provider the name of the provider with which to register
minTime minimum time interval between location updates, in milliseconds
minDistance minimum distance between location updates, in meters
listener a LocationListener whose onLocationChanged(Location) method will be called for each location update
you should implement locationlistener in your activity
private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; // 10 meters
// The minimum time between updates in milliseconds
private static final long MIN_TIME_BW_UPDATES = 1000 * 60 * 1; // 1 minute
boolean isGPSEnabled = false;
LocationManager locationManager = (LocationManager) yourapplicationcontext
.getSystemService(LOCATION_SERVICE);
// getting GPS status
isGPSEnabled = locationManager
.isProviderEnabled(LocationManager.GPS_PROVIDER);
if (isGPSEnabled) {
if (location == null) {
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Log.d("GPS Enabled", "GPS Enabled");
if (locationManager != null) {
location = locationManager
.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
}
//Add this permission
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />

Categories

Resources