mlevit
mlevit

Reputation: 2736

getContentLength() returning -1 on some devices and not others

I'm trying to obtain the size of a file before I download it. I use conn.getContentLength(); to do this and it works fine on my home computers Android 2.1 Emulator.

It however doesn't work once I run my app from my phone (either WiFi or 3G) and it also doesn't work when I run it from my work laptops Android 2.1 Emulator.

Does anyone know a workaround for this? Is there another way I can obtain the size of the file maybe without using HttpURLConnection.

Upvotes: 1

Views: 3030

Answers (2)

Someone Somewhere
Someone Somewhere

Reputation: 23787

Use HttpVersion.HTTP_1_0 for your file downloads. This prevents the use of "Chunked transfer encoding"

See: http://en.wikipedia.org/wiki/Chunked_transfer_encoding

For example, overload the constructor so that you can specify which HTTP version:

public class HTTPrequest
{
    //member variables
    private SchemeRegistry mSchemeRegistry;
    private HttpParams mHttpParams;
    private SingleClientConnManager mSCCmgr;
    private HttpClient mHttpClient;
    private HTTPrequestListener mHTTPrequestListener = null;

    //constants
    private final int TIMEOUT_CONNECTION = 20000;//20sec
    private final int TIMEOUT_SOCKET = 30000;//30sec

    //interface for callbacks
    public interface HTTPrequestListener
    {
        public void downloadProgress(int iPercent);
    }

    /**
     * Creates an HttpClient that uses plain text only.
     * note: Default constructor uses HTTP 1.1
     */
    public HTTPrequest()
    {
        this(HttpVersion.HTTP_1_1);
    }

    /**
     * Creates an HttpClient that uses plain text only.
     * @param httpVersion HTTP Version (0.9, 1.0, 1.1)
     */
    public HTTPrequest(HttpVersion httpVersion)
    {
        //define permitted schemes
        mSchemeRegistry = new SchemeRegistry();
        mSchemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));

        //define http parameters
        mHttpParams = new BasicHttpParams();
        HttpConnectionParams.setConnectionTimeout(mHttpParams, TIMEOUT_CONNECTION);
        HttpConnectionParams.setSoTimeout(mHttpParams, TIMEOUT_SOCKET);
        HttpProtocolParams.setVersion(mHttpParams, httpVersion);
        HttpProtocolParams.setContentCharset(mHttpParams, HTTP.UTF_8);

        //tie together the schemes and parameters
        mSCCmgr = new SingleClientConnManager(mHttpParams, mSchemeRegistry);

        //generate a new HttpClient using connection manager and parameters
        mHttpClient = new DefaultHttpClient(mSCCmgr, mHttpParams);
    }

    public void setHTTPrequestListener(HTTPrequestListener httpRequestListener)
    {
        mHTTPrequestListener = httpRequestListener;
    }

    //other methods for POST and GET
}

When you want to do a file download use HTTPrequest httpRequest = new HTTPrequest(HttpVersion.HTTP_1_0); and when you want to do a POST or GET use HTTPrequest httpRequest = new HTTPrequest();

Upvotes: 0

Erick Robertson
Erick Robertson

Reputation: 33068

This information will not always be available. Usually you will know the length of the file you are downloading. Depending on the webserver, the protocol, the connection, and the method of downloading, this information may not always be available.

You should definitely modify your application so that it can handle this situation. I think you will find that different devices using different connection methods will offer different results with this.

Upvotes: 1

Related Questions