Android: Downloading and Saving an Image to Internal Storage.

By Paulus, 15 November, 2013

I'm currently working on a mobile application for work that requires images to be updated. I am also downloading an XML file that contains from a remote location. Within the XML file is a node containing a URL to download an image. Downloading and storing the XML is easy enough:

try {

	File fileEvents = new File(context.getFilesDir().getAbsolutePath() + "/events.xml");

	if (fileEvents.exists()) {
		fileEvents.delete();
	}

	String buffer;
	URLConnection conn = new URL(CALLBACK_URL).openConnection();
	conn.setUseCaches(false);
	conn.connect();
	InputStreamReader isr = new InputStreamReader(conn.getInputStream());
	BufferedReader br = new BufferedReader(isr);

	FileOutputStream fos = context.openFileOutput("events.xml",	Context.MODE_PRIVATE);

	while ((buffer = br.readLine()) != null) {
		fos.write(buffer.getBytes());
	}

	fos.close();
	br.close();
	isr.close();

} catch (IOException ioe) {

}

Using the same method does not work for images. No exceptions were thrown pointing to what the cause was which made tracking down the problem very difficult. The only thing I had to go oon was a message in the LogCat window: skimagedecoder factory returned null. After spending a lot of time trying to track down where the problem was I eventual saw that the downloaded image from Chrome and the file downloaded using my code had different sizes. What I found is that the image downloaded using the above method resulted in additional data being written which caused the decoding to fail. To overcome this problem I modified my code to the following:

try {
	URL url = new URL(strUrl);
	HttpURLConnection conn = (HttpURLConnection) url.openConnection();
	conn.setDoInput(true);
	conn.connect();
	InputStream is = conn.getInputStream();
	Bitmap bm = BitmapFactory.decodeStream(is);
	FileOutputStream fos = context.openFileOutput(fileName, Context.MODE_PRIVATE);

	ByteArrayOutputStream outstream = new ByteArrayOutputStream();

	bm.compress(Bitmap.CompressFormat.JPEG, 100, outstream);
	byte[] byteArray = outstream.toByteArray();

	fos.write(byteArray);
	fos.close();
} catch(Exception e) {

}