Question

I've got a problem when I try to find my current location that I need to display the weather. This is the method I use to find my location:

protected class GetPosition extends AsyncTask<String, Void, String> {
        protected String doInBackground(String... params) {

            List<Address> addresses = null;
            try {
                LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
                Location location = lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                double longitude = location.getLongitude();
                double latitude = location.getLatitude();
                Geocoder gcd = new Geocoder(getApplicationContext(), Locale.getDefault());
                addresses = gcd.getFromLocation(latitude, longitude, 1);
                if (addresses.size() > 0) return addresses.get(0).getLocality();
            } catch (Exception e) {
                return "Nessuna posizione disponibile";
            }
            return addresses.get(0).getLocality();
        }

        @Override
        protected void onPostExecute(String s) {
            super.onPostExecute(s);
            citylb.setText(s);
            getWeather((String) citylb.getText());


        }
    }

and this is the way I check if there is some connection like data or wifi:

public boolean isOnline() {
        ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo netInfo = cm.getActiveNetworkInfo();
        if (netInfo != null || netInfo.isConnectedOrConnecting()) { //Here crashes
            return true;
        }
        return false;
    }
private void getWeather(String location) {
        if (isOnline()) {
            Log.d("YWeatherGetter4a", "onCreate");
            YahooWeatherUtils yahooWeatherUtils = YahooWeatherUtils.getInstance();
            yahooWeatherUtils.queryYahooWeather(getApplicationContext(), location, this);
        } else
            Toast.makeText(getApplicationContext(), "Sorry, no connection available", Toast.LENGTH_SHORT).show();

    }

I've got two problems:

1) If I am without any connection, the application crashes at the line if (netInfo != null || netInfo.isConnectedOrConnecting()), netInfo seems null.

2) The location isn't always correct. Frequently it returns an "old" location and not current. Example: if two hours ago, I was at Rome and now in Milano, it shows me Rome. I can't understand where I'm wrong.

About first problem I tried also writing: if (netInfo != null && netInfo.isConnectedOrConnecting()) with the && instead ||. Not crashes but it finds the location only in wifi and not in data connection. How can I solve these problems? Thanks

Was it helpful?

Solution

  1. You are using getLastKnownLocation() to get location but You doesn't use

    locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 2000, 0, null);

The second parameter is delation between updates in milliseconds. The fourth parameter is listener, you can use it to update locations vithout any async threads, for example:

...
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 2000, 0, this);
...

public void onLocationChanged(Location arg0) {
    if (arg0 != null){
        double longitude = arg0.getLongitude();
        double latitude = arg0.getLatitude();

        ...
    }
}
  1. LocationManager.NETWORK_PROVIDER is no good way to recieve location because it using location recieved by another location services when device was near wifi router. If location was not recieved near some router by another services in some reasons it will not provide you correct location.

  2. There is a bug in some devices (for example Sony) when mobile data turned on and networkInfo == null. Some times it solves getting needed networkInfo directly. For Exmple:

    android.net.NetworkInfo wifi = cm.getNetworkInfo(ConnectivityManager.TYPE_WIFI); android.net.NetworkInfo mobile = cm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);

Example:

public class MyActivity extends Activity implements LocationListener
{

    ...

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        ...

        locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);

        ... // do something

        locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 2000, // every 2 seconds
                0, this);
    }

    ...

    public void onLocationChanged(Location arg0) {
        if (arg0 != null){
            double longitude = arg0.getLongitude();
            double latitude = arg0.getLatitude();

            ...
        }
    }

}

OTHER TIPS

When you are using the getLastKnowLocation method, you are getting the last location that was returned by the given provider. If that provider hasn't been used for a while by any other application, the location returned will be old. In such a case, you should use one of the requestLocationUpdates (http://developer.android.com/reference/android/location/LocationManager.html) method family, the one that suits your needs.

Regarding the crash, you should include the following permission on your manifest:

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

1)

Already answered but here is my isOnline() implementation anyways:

public Boolean isOnline() {
    ConnectivityManager cm = (ConnectivityManager) context
            .getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo ni = cm.getActiveNetworkInfo();
    if (ni != null && ni.isConnected())
        return true;

    return false;
}

2)

Also already answered - it is the expected behavior.

However, I have implemented some code that fires the GPS and issues a callback as soon as a valid new position is found (GPS-firstfix). You can find the code in my answer to this question: Location servise GPS Force closed

When the valid position has been obtained you can simply stop the GPS immediately after.

  1. The if condition should be

    if(netInfo != null && netInfo.isConnectedOrConnecting())

The way || operator works is if the first condition is false, it will test the second condition as well.

  1. getLastKnownLocation will provide you the last updated location, instead of fetching the current location. The location might have been requested by another application, giving you correct results sometimes. If you need updated location, you need to register a LocationListener (refer docs)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top