24

How can I save an images to the SD card that I retrieve from the image's URL?

Jeff Axelrod
  • 27,676
  • 31
  • 147
  • 246
Jameskittu
  • 598
  • 2
  • 8
  • 17
  • @Akusete... you should replace 'buffer.length' in output.write(buffer, 0, buffer.length); to bytesRead. Otherwise garbage data will be appended at the end of the file. – shaffooo Jun 27 '11 at 18:53

2 Answers2

47

First you must make sure your application has permission to write to the sdcard. To do this you need to add the uses permission write external storage in your applications manifest file. See Setting Android Permissions

Then you can you can download the URL to a file on the sdcard. A simple way is:

URL url = new URL ("file://some/path/anImage.png");
InputStream input = url.openStream();
try {
    //The sdcard directory e.g. '/sdcard' can be used directly, or 
    //more safely abstracted with getExternalStorageDirectory()
    File storagePath = Environment.getExternalStorageDirectory();
    OutputStream output = new FileOutputStream (new File(storagePath,"myImage.png"));
    try {
        byte[] buffer = new byte[aReasonableSize];
        int bytesRead = 0;
        while ((bytesRead = input.read(buffer, 0, buffer.length)) >= 0) {
            output.write(buffer, 0, bytesRead);
        }
    } finally {
        output.close();
    }
} finally {
    input.close();
}

EDIT : Put permission in manifest

 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Bhavesh Hirpara
  • 22,255
  • 15
  • 63
  • 104
Akusete
  • 10,704
  • 7
  • 57
  • 73
  • 1
    @Paresh: Thanks, I've updated the code to use `getExternalStorageDirectory()`. Do you know if it returns a trailing slash? e.g. `/sdcard` or `/sdcard/` – Akusete Mar 16 '12 at 04:25
  • 1
    Your question is moot because `Environment.getExternalStorageDirectory()` does not return a `String` and therefore your code does not compile. I corrected your code for you. – Jeff Axelrod Aug 10 '12 at 20:24
  • 2
    aReasonableSize is a size that wont give you out of memory exceptions. Usually 1024 or 2048 will do. – Lazy Ninja Dec 07 '12 at 09:11
8

An excellent example can be found in the latest post on Android developer's blog:

static Bitmap downloadBitmap(String url) {
    final AndroidHttpClient client = AndroidHttpClient.newInstance("Android");
    final HttpGet getRequest = new HttpGet(url);

    try {
        HttpResponse response = client.execute(getRequest);
        final int statusCode = response.getStatusLine().getStatusCode();
        if (statusCode != HttpStatus.SC_OK) { 
            Log.w("ImageDownloader", "Error " + statusCode + 
               " while retrieving bitmap from " + url); 
            return null;
        }

        final HttpEntity entity = response.getEntity();
        if (entity != null) {
            InputStream inputStream = null;
            try {
                inputStream = entity.getContent(); 
                final Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
                return bitmap;
            } finally {
                if (inputStream != null) {
                    inputStream.close();  
                }
                entity.consumeContent();
            }
        }
    } catch (Exception e) {
        // Could provide a more explicit error message for IOException or
        // IllegalStateException
        getRequest.abort();
        Log.w("ImageDownloader", "Error while retrieving bitmap from " + url,
           e.toString());
    } finally {
        if (client != null) {
            client.close();
        }
    }
    return null;
}
Jeff Axelrod
  • 27,676
  • 31
  • 147
  • 246
ognian
  • 11,451
  • 4
  • 35
  • 33