peterp
peterp

Reputation: 171

Android service - data connection lost and can't restore

The background of my service: it implements LocationListener and in LocationManager instance (locMananager) registers for updates:

manager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);

In onLocationChanged method it calls a method named recordTrace with a current location, which then calls getHttpResponse to send the location coordinates to a server. The latter method is as follows:

    public InputStream getHttpResponse(String url, ArrayList<NameValuePair> params, int timeout) throws Exception {
    DefaultHttpClient httpClient = new DefaultHttpClient();
    HttpParams httpParams = new BasicHttpParams();
    HttpConnectionParams.setConnectionTimeout(httpParams, timeout);
    httpClient.setParams(httpParams);
    HttpPost post = new HttpPost(url);
    if(params != null && !params.isEmpty()) {
        try {
            post.setEntity(new UrlEncodedFormEntity(params));
        } catch (UnsupportedEncodingException e) {
            Log.e(TAG, "HttpPost.setEntity Error: " + e.getMessage());
            lastError = "błąd HTTP";
        }
    }
    CookieStore store = new BasicCookieStore();
    if(localCookies != null && localCookies.size() > 0) {
        for(int i = 0; i < localCookies.size(); i++) {
            store.addCookie(localCookies.get(i));
        }
    }
    HttpContext context = new BasicHttpContext();
    context.setAttribute(ClientContext.COOKIE_STORE, store);
    HttpResponse response = null;
    HttpEntity entity = null;
    InputStream content = null;
    try {
        response = httpClient.execute(post, context);
        store = (CookieStore) context.getAttribute(ClientContext.COOKIE_STORE);
        List<Cookie> cookies = store.getCookies();
        if(cookies != null && cookies.size() > 0) {
            localCookies = new ArrayList<BasicClientCookie>();
            for(Cookie cookie : cookies) {
                localCookies.add((BasicClientCookie) cookie);
            }
        }
        entity = response.getEntity();
        content = entity.getContent();
        return content;
    } catch (ClientProtocolException e) {
        throw e;
    } catch (IOException e) {
        throw e;
    } catch (Exception e) {
        throw e;
    }
}

params is a NameValuePair with prepared data, timeout is set to 5000 (5 seconds). ArrayList localCookies holds cookies saved before, after successful logging in (to keep the session).

The problem is: when I loose a mobile signal (i.e. when I go to a subway) and restore it, I get IOException, which is unrecoverable unless I restart the phone.

Any help would be appreciated. I'm loosing my mind and going bald!

Thanks, Peter.

EDIT I've done some research. After the method getHttpResponse is invoked, I utilize InputStream returned by it, but don't close it after all. Do you thing that might be the issue? Is this possible that the operator breaks the connection and then establishes a new one, whereas my InputStream somehow "keeps" the former connection and produces the problems with data transfer?

I added a finally block where now the InputSTream is closed. However, since it's hard to cause the problem on demand (it doesn't happen regularly), I can't check if closing stream solves it.

Upvotes: 1

Views: 816

Answers (1)

peterp
peterp

Reputation: 171

After a few days of testing it seems I've found the solution. Calling 2 methods solves the issue:

  1. close the InputStream returned by httpResponse.getEntity()

  2. shutdown the connection by executing httpClient.getConnectionManager().shutdown()

Code snippet of a complete request and response handling:

String url = "www.someurl.com";
ArrayList<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("login", "mylogin"));
params.add(new BasicNameValuePair("password", "mypassword"));
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
try {
    httpPost.setEntity(new UrlEncodedFormEntity(params));
    HttpResponse httpResponse = httpClient.execute(httpPost);
    HttpEntity httpEntity = httpResponse.getEntity();
    InputStream content = httpEntity.getContent();
    /*
     * utilize content here...
     */
    content.close();    // here's the point
    httpClient.getConnectionManager().shutdown();   // the second important thing
}
catch (UnsupportedEncodingException e) {}
catch (ClientProtocolException e) {}
catch (IOException e) {}

I'm answering my own question since I've spent a lot of time on searching what's causing the problem and I think I can save somebody's time. After a few days the aplication is still working and doesn't break the connection.

Regards,

Peter.

Upvotes: 1

Related Questions