Search code examples
androidandroid-image

Downloaded Image not complete but the image still shows cut using Android?


I have an Android application that downloads some images, using normally. Most of the times, when an error occurs (network, disk space, ...etc) an exception is thrown, an I just know and delete the downloaded file in catch block.

However, sometimes, the download is not complete and the image is shown but cut off. (i.e. half of image is visible and the left part is shown white)

Any suggestions on how to detect this error so that I delete the file and request the user to download it again?

Here is code:

private static int downloadFile(byte[] buffer, String fromUrl, File saveTo) {
    URL url;
    boolean conn = true;
    try {
        url = new URL(fromUrl);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setRequestProperty("connection", "close");
        connection.connect();
        // expect HTTP 200 OK, so we don't mistakenly save error report
        // instead of the file
        if (connection.getResponseCode() != HttpURLConnection.HTTP_OK)
            return DOWNLOAD_SERVER_INVALID_RESPONSE;
        //int fileLength = connection.getContentLength();
        // download the file
        InputStream input = connection.getInputStream();
        conn = false;
        FileOutputStream output = new FileOutputStream(saveTo);
        int count;
        //long total = 0;
        while ((count = input.read(buffer)) != -1) {
            output.write(buffer, 0, count);
            //total += count;
        }
        input.close();
        output.close();
        return DOWNLOAD_OK;
    } catch (MalformedURLException e) {
        e.printStackTrace();
        return DOWNLOAD_MALFORMED_URL;
    } catch (FileNotFoundException e) {
        e.printStackTrace();
        return DOWNLOAD_FILE_NOT_FOUND;
    } catch (SocketException ex) {
        ex.printStackTrace();
        return DOWNLOAD_SERVER_INVALID_RESPONSE;
    } catch (UnknownHostException ex) {
        ex.printStackTrace();
        return DOWNLOAD_SERVER_INVALID_RESPONSE;
    } catch (IOException e) {
        e.printStackTrace();
        return conn ? DOWNLOAD_SERVER_INVALID_RESPONSE : DOWNLOAD_IO_EXCEPTION;
    }
}

Solution

  • Well I guess since the image you explained is a half downloaded image, you could do something like check how much of the image was actually downloaded, and then decide whether to delete or keep based on that. In you code , the line int fileLength = connection.getContentLength(); will help you do this. Just check if fileLength and the downloaded image file length is equal or near to be equal. If it is, then it has been downloaded successfully. I'm guessing, just guessing, that the code would be something like this:

    int fileLength = connection.getContentLength();
    if (fileLength != -1) {
        if (fileLength == file.length()) {
            System.out.println("file is complete");
        } else {
            System.out.println("file is incomplete");
        }
    } else {
        System.out.println("unknown if file is complete");
    }
    

    Tweak it a little and you should probably get what you want.

    OR

    As greenapps pointed out, you could also use this approach:

    1. Assign an int variable int totalcount = 0;
    2. Increment that in a loop with totalcount += count;
    3. After the loop is complete, compare totalcount with fileLength