0

Before making an HttpRequest to Google Places, I need to check for a connection.

If there is no active connection, it will display "No Connection" to the user, otherwise it will get the current location and perform the request.

Some test cases:

a) 1. Enable connection -> Gets data fine, 2. Again -> Gets data fine

b) 1. No connection -> "No Connection", 2. Enable connection -> Gets data fine

c) 1. Enable connection -> Gets data fine, 2. Disable connection -> "No Connection"

Good so far, but then

d) 1. Active Connection -> Gets data fine, 2. Disable connection -> "No Connection", 3. Enable Connection -> "Write error: ssl=0x5a90fbb0: I/O error during system call, Broken pipe"

I have log statements confirming that the location data is correct before the HttpRequest in the 3rd step of test case d). So I cannot see any reason why it is failing.

Code as requested:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.results);

// set up location manager to work with location service
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

if (checkInternet()) {

    currentLocation = locationManager
                .getLastKnownLocation(LocationManager.NETWORK_PROVIDER);

    location = currentLocation.getLatitude() + ","
                    + currentLocation.getLongitude();

    places = new PlaceList();

    // keyword is passed in from previous activity
    Intent intent = this.getIntent();
        keyword = intent.getStringExtra("keyword");

        if (keyword != "") {

            class GoogleRequest extends AsyncTask<Void, Void, Integer> {

                protected Integer doInBackground(Void... params) {
                    mht = MyHttpTransport.createRequestFactory();
                    Resources res = getResources();
                    try {
                        HttpRequest request = mht
                                .buildGetRequest(new GenericUrl(
                                        res.getString(R.string.places_search_url)));
                        request.getUrl().put("key",
                                res.getString(R.string.google_places_key));
                        request.getUrl().put("location", location);
                        request.getUrl().put("radius", Config.RADIUS);
                        request.getUrl().put("keyword", keyword);
                        request.getUrl().put("sensor", false);

                        places = request.execute().parseAs(
                                PlaceList.class);

                                } catch (IOException e) {
                        Log.e(Config.MSGTAG, e.getMessage());
                    }

                    return null;
                }

                @Override
                protected void onPostExecute(Integer result) {
        // details omitted because it fails to 
        // get data from the places field
                }

            }

@Override
protected void onResume() {
    super.onResume();

    locationManager.requestLocationUpdates(
            LocationManager.NETWORK_PROVIDER, 5000, 100, this);
}

@Override
protected void onPause() {
    super.onPause();
    locationManager.removeUpdates(this);
}

@Override
public void onLocationChanged(Location location) {
    locationManager.removeUpdates(this);
    currentLocation = location;
}

public boolean checkInternet() {
    ConnectivityManager cm = (ConnectivityManager) this
            .getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo wifi = cm.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
    NetworkInfo mobile = cm
            .getNetworkInfo(ConnectivityManager.TYPE_MOBILE);

    if (wifi.isConnected()) {
        return true;
    } else if (mobile.isConnected()) {
        return true;
    }
    return false;
    }
}

Log:

02-15 19:34:32.582: E/*(9967): Write error: ssl=0x5efd0a98: I/O error during system call, Broken pipe

the rest of the log is the postExecute() but that's irrelevant.

Gideon Pyzer
  • 22,610
  • 7
  • 62
  • 68
  • 2
    Post your code, and the exact crash trace from your logcat. Also, you can't make an HTTP request in onResume, it will throw an exception because you'd block the UI thread. You need to do it in an AsyncTask or thread. – Gabe Sechan Feb 15 '13 at 19:13
  • I have added the code @GabeSechan - I do use AsyncTask. – Gideon Pyzer Feb 15 '13 at 19:31
  • I have also added the relevant log @GabeSechan – Gideon Pyzer Feb 15 '13 at 19:35
  • You're dereferencing a null variable on line 282, which is in onResume. The only variable I see there which could be null is locationManager. Do you null it out somewhere? Or possibly this isn't the exact version of code you were running. – Gabe Sechan Feb 15 '13 at 19:36
  • locationManager is never null because it gets assigned on onCreate() each time. The location and keyword exist before the HttpRequest is made because I print them in the logs. They show up just before it crashes. So is it something to do with Android not liking the fact I turned the Internet off and on again? @GabeSechan – Gideon Pyzer Feb 15 '13 at 19:42
  • I think it may be related to [this](http://code.google.com/p/android/issues/detail?id=8625). I have it working now. – Gideon Pyzer Feb 15 '13 at 21:12

1 Answers1

0

I have solved the problem.

In my custom HttpTransport class, I have a final ApacheHttpTransport object, which gets re-used every time createRequestFactory() method is called. The problem seems to be that when the connection is lost, and then a new connection is created, it tries to use the old one (something along those lines). So to get around this, I create a new ApacheHttpTransport object inside the createRequestFactory() method.

Gideon Pyzer
  • 22,610
  • 7
  • 62
  • 68