Download Image in Android

Introduction

 
This article shows how to download an image and store it in the SD card of your Android phone.
 
We will be using the Universal Image Loader for displaying a list of images. The user will be able to download the image by clicking on the image in the image list displayed.
Refer to Universal Image Loader article for writing the universal image loader part.
 
Step 1
 
A small change is required in "listOfImages.java", Start the activity "Download" (created later) to load it when any item of the list is clicked.
  1. package com.chhavi.downloadimage;  
  2.    
  3. import java.util.Collections;  
  4. import java.util.LinkedList;  
  5. import java.util.List;  
  6. import android.app.Activity;  
  7. import android.content.Context;  
  8. import android.content.Intent;  
  9. import android.os.Bundle;  
  10. import android.view.View;  
  11. import android.view.ViewGroup;  
  12. import android.widget.AbsListView;  
  13. import android.widget.AdapterView;  
  14. import android.widget.BaseAdapter;  
  15. import android.widget.ImageView;  
  16. import android.widget.ListView;  
  17. import android.widget.TextView;  
  18. import com.nostra13.universalimageloader.core.DisplayImageOptions;  
  19. import com.nostra13.universalimageloader.core.ImageLoader;  
  20. import com.nostra13.universalimageloader.core.assist.ImageLoadingListener;  
  21. import com.nostra13.universalimageloader.core.assist.SimpleImageLoadingListener;  
  22. import com.nostra13.universalimageloader.core.display.RoundedBitmapDisplayer;  
  23.    
  24. public class ListOfImages extends Activity {  
  25.         protected AbsListView list;  
  26.         protected ImageLoader loader = ImageLoader.getInstance();  
  27.    
  28.        final Context context=this;  
  29.     DisplayImageOptions op;  
  30.     String [] images={"http://t2.gstatic.com/images?q=tbn:ANd9GcSZrajzoEXNlRWjMGE9L3kqI1EsFN9P5HCNhMo4xaqLkWuhAixo","http://t0.gstatic.com/images?q=tbn:ANd9GcQH7hisM_szjOKlVdQvq6m_J4lETkWxQOlAk3SMWs051TFFnmWMCA","http://3.bp.blogspot.com/-kAhN0HX-MBk/T_5bApfhbJI/AAAAAAAAAuI/lUww8xT9yV8/s1600/smileys_001_01.png"};   
  31.      
  32.     @Override  
  33.     public void onCreate(Bundle savedInstanceState) {  
  34.         super.onCreate(savedInstanceState);  
  35.         setContentView(R.layout.image_listview_layout);  
  36.    
  37.         op = new DisplayImageOptions.Builder()  
  38.                 .showStubImage(R.drawable.ic_stub)  
  39.                 .showImageForEmptyUri(R.drawable.ic_empty)  
  40.                 .cacheInMemory()  
  41.                 .cacheOnDisc()  
  42.                 .displayer(new RoundedBitmapDisplayer(20))  
  43.                 .build();  
  44.    
  45.         list = (ListView) findViewById(android.R.id.list);  
  46.         ((ListView) list).setAdapter(new ItemAdapter());  
  47.         list.setOnItemClickListener(new AdapterView.OnItemClickListener() {  
  48.             @Override  
  49.             public void onItemClick(AdapterView<?> parent, View view, int position, long id) {  
  50.                
  51.               Intent i=new Intent(context,Download.class);  
  52.               i.putExtra("pos",position+"");  
  53.               startActivity(i);  
  54.             }  
  55.         });  
  56.     }  
  57.    
  58.     @Override  
  59.     public void onBackPressed() {  
  60.           super.onBackPressed();  
  61.     }  
  62.    
  63.    
  64.     class ItemAdapter extends BaseAdapter {  
  65.    
  66.         private class ViewHolder {  
  67.             public TextView text;  
  68.             public ImageView image;  
  69.         }  
  70.    
  71.         @Override  
  72.         public int getCount() {  
  73.             return images.length;  
  74.         }  
  75.    
  76.         @Override  
  77.         public Object getItem(int position) {  
  78.             return position;  
  79.         }  
  80.    
  81.         @Override  
  82.         public long getItemId(int position) {  
  83.             return position;  
  84.         }  
  85.    
  86.         @Override  
  87.         public View getView(final int position, View convertView, ViewGroup parent) {  
  88.             View v = convertView;  
  89.             final ViewHolder holder;  
  90.             if (convertView == null) {  
  91.                 v = getLayoutInflater().inflate(R.layout.image_list_layout, parent, false);  
  92.                 holder = new ViewHolder();  
  93.                 holder.text = (TextView) v.findViewById(R.id.text);  
  94.                 holder.image = (ImageView) v.findViewById(R.id.image);  
  95.                 v.setTag(holder);  
  96.             } else {  
  97.                 holder = (ViewHolder) v.getTag();  
  98.             }  
  99.    
  100.             holder.text.setText("Image " + (position + 1));  
  101.             loader.displayImage(images[position], holder.image, op, null);  
  102.    
  103.             return v;  
  104.         }  
  105.     }     
  106.   }  
This is the same old code as you saw in the "Universal Image Loader" article. The only change is the starting of the activity "Download" on item click. 
 
Step 2
 
Make a new layout file and name it as "progress_dialog_layout.xml" and add the following code to it:
  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.               android:id="@+id/layout_root"  
  3.               android:orientation="vertical"  
  4.               android:layout_width="fill_parent"  
  5.               android:layout_height="fill_parent"  
  6.               android:padding="10dp">  
  7.     <TextView  
  8.             android:id="@+id/downloadingFrom"  
  9.             android:layout_width="wrap_content"  
  10.             android:layout_height="wrap_content"  
  11.             android:textColor="#FFF"  
  12.             android:text="hello"  
  13.             android:textStyle="bold"/>  
  14.     <TextView  
  15.             android:id="@+id/startDownload"  
  16.             android:layout_width="wrap_content"  
  17.             android:layout_height="wrap_content"  
  18.             android:textColor="#b22f2f"  
  19.             android:text="hello"  
  20.             android:layout_marginTop="5dp"  
  21.             android:textStyle="bold|italic"    />  
  22.     <ProgressBar  
  23.             android:id="@+id/progress_bar"  
  24.             android:layout_width="fill_parent"  
  25.             android:layout_height="wrap_content"  
  26.             android:progress="0"  
  27.             android:layout_marginTop="5dp"  
  28.             android:layout_marginBottom="10dp"  
  29.             style="?android:attr/progressBarStyleHorizontal"  
  30.             android:maxHeight="10dip"  
  31.             android:minHeight="10dip"  
  32.             />  
  33. </LinearLayout> 
Step 3
 
Make a new drawable resource file. Name it "show_progress_slider.xml" and add the following code to it:
  1. <layer-list xmlns:android="http://schemas.android.com/apk/res/android">  
  2.     <item android:id="@android:id/background">  
  3.         <shape>  
  4.             <corners android:radius="5dip" />  
  5.             <gradient  
  6.                     android:startColor="#ff9d9e9d"  
  7.                     android:centerColor="#ff5a5d5a"  
  8.                     android:centerY="0.75"  
  9.                     android:endColor="#ff747674"  
  10.                     android:angle="270"  />  
  11.         </shape>  
  12.     </item>  
  13.     <item  
  14.             android:id="@android:id/progress">  
  15.         <clip>  
  16.             <shape>  
  17.                 <corners  
  18.                         android:radius="5dip" />  
  19.                 <gradient  
  20.                         android:startColor="#ff8e8e"  
  21.                         android:centerColor="#ff5656"  
  22.                         android:centerY="0.75"  
  23.                         android:endColor="#ffa1a1"  
  24.                         android:angle="270"  
  25.                         />  
  26.             </shape>  
  27.         </clip>  
  28.     </item>  
  29. </layer-list>  
Step 4
  1. package com.chhavi.downloadimage;    
  2.      
  3. import android.os.Bundle;    
  4. import android.app.Activity;    
  5. import android.util.Log;    
  6. import android.view.Menu;    
  7. import java.io.File;    
  8. import java.io.FileOutputStream;    
  9. import java.io.IOException;    
  10. import java.io.InputStream;    
  11. import java.net.HttpURLConnection;    
  12. import java.net.MalformedURLException;    
  13. import java.net.URL;    
  14. import android.app.Activity;    
  15. import android.app.Dialog;    
  16. import android.content.Intent;    
  17. import android.os.Bundle;    
  18. import android.os.Environment;    
  19. import android.view.View;    
  20. import android.view.Window;    
  21. import android.view.View.OnClickListener;    
  22. import android.widget.Button;    
  23. import android.widget.ProgressBar;    
  24. import android.widget.TextView;    
  25. import android.widget.Toast;    
  26.      
  27. public class Download extends Activity {    
  28.           
  29.         String [] images={"http://t2.gstatic.com/images?q=tbn:ANd9GcSZrajzoEXNlRWjMGE9L3kqI1EsFN9P5HCNhMo4xaqLkWuhAixo","http://t0.gstatic.com/images?q=tbn:ANd9GcQH7hisM_szjOKlVdQvq6m_J4lETkWxQOlAk3SMWs051TFFnmWMCA","http://3.bp.blogspot.com/-kAhN0HX-MBk/T_5bApfhbJI/AAAAAAAAAuI/lUww8xT9yV8/s1600/smileys_001_01.png"};    
  30.      
  31.     ProgressBar progress;    
  32.     Dialog dialog;    
  33.     int downloadedSize = 0;    
  34.     int totalSize = 0;    
  35.     TextView showProgressInText;    
  36.     String path = "null";    
  37.     int pos=-1;    
  38.      
  39.     @Override    
  40.     public void onCreate(Bundle savedInstanceState) {    
  41.         super.onCreate(savedInstanceState);    
  42.         setContentView(R.layout.activity_main);    
  43.         Intent i=getIntent();    
  44.         pos=Integer.parseInt(i.getStringExtra("pos"));    
  45.         path=images[pos];    
  46.         Log.i("url of image being downloaded...*************........",path);    
  47.         progressBarShow(path);    
  48.      
  49.         new Thread(new Runnable() {    
  50.             public void run() {    
  51.                      downloadImage();    
  52.                 }    
  53.              }).start();           
  54.     }    
  55.      
  56.     void downloadImage(){    
  57.      
  58.         try {    
  59.             URL url = new URL(path);    
  60.             HttpURLConnection con = (HttpURLConnection) url.openConnection();    
  61.      
  62.             con.setRequestMethod("GET");    
  63.             con.setDoOutput(true);    
  64.      
  65.             con.connect();    
  66.      
  67.             File sdcardPath = Environment.getExternalStorageDirectory();    
  68.                
  69.             Log.i("saving path....*******...",""+Environment.getExternalStorageDirectory() );    
  70.               
  71.             File file = new File(sdcardPath,"downloaded_imagex"+pos+".png");    
  72.      
  73.             FileOutputStream output = new FileOutputStream(file);    
  74.             InputStream input = con.getInputStream();    
  75.             totalSize = con.getContentLength();    
  76.      
  77.             runOnUiThread(new Runnable() {    
  78.                 public void run() {    
  79.                            progress.setMax(totalSize);    
  80.                 }    
  81.             });    
  82.      
  83.             byte[] buffer = new byte[1024];    
  84.             int bufferLength = 0;    
  85.      
  86.             while ( (bufferLength = input.read(buffer)) > 0 ) {    
  87.                 output.write(buffer, 0, bufferLength);    
  88.                 downloadedSize += bufferLength;    
  89.                  
  90.                 runOnUiThread(new Runnable() {    
  91.                     public void run() {    
  92.                         progress.setProgress(downloadedSize);    
  93.                         float per = ((float)downloadedSize/totalSize) * 100;    
  94.                         showProgressInText.setText("Downloaded " + downloadedSize + "KB / " + totalSize + "KB (" + (int)per + "%)" );    
  95.                     }    
  96.                 });    
  97.             }    
  98.              
  99.             output.close();    
  100.             runOnUiThread(new Runnable() {    
  101.                 public void run() {                      
  102.                 }    
  103.             });    
  104.      
  105.         }    
  106.         catch (final Exception e) {    
  107.             showError("Connection error...... " + e);    
  108.         }    
  109.     }    
  110.      
  111.     void showError(final String err){    
  112.         runOnUiThread(new Runnable() {    
  113.             public void run() {    
  114.                 Toast.makeText(Download.this, err, Toast.LENGTH_LONG).show();    
  115.                   
  116.             }    
  117.         });    
  118.     }    
  119.      
  120.     void progressBarShow(String file_path){    
  121.         dialog = new Dialog(Download.this);    
  122.         dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);    
  123.         dialog.setContentView(R.layout.progress_dialog_layout);    
  124.         dialog.setTitle("Downloading......");    
  125.      
  126.         TextView text = (TextView) dialog.findViewById(R.id.downloadingFrom);    
  127.         text.setText("Downloading file from ... " + file_path);    
  128.         showProgressInText = (TextView) dialog.findViewById(R.id.startDownload);    
  129.         showProgressInText.setText("Starting download...");    
  130.         dialog.show();    
  131.      
  132.         progress = (ProgressBar)dialog.findViewById(R.id.progress_bar);    
  133.         progress.setProgress(0);    
  134.         progress.setProgressDrawable(getResources().getDrawable(R.drawable.show_progress_slider));    
  135.     }    
  136. }   
The HttpURLConnection class helps in sending and receiving the data over the web.
 
"sdCardPath" is the path where the downloaded image will be stored to.
 
The image file is being transferred by converting it into a File stream.
 
Step 5
 
Do the following changes in "AndroidManifest":
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     package="com.chhavi.downloadimage"  
  4.     android:versionCode="1"  
  5.     android:versionName="1.0" >  
  6.      
  7.     <uses-permission android:name="android.permission.INTERNET" />  
  8.     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />  
  9.    
  10.     <uses-sdk  
  11.         android:minSdkVersion="8"  
  12.         android:targetSdkVersion="17" />  
  13.    
  14.     <application  
  15.         android:name=".App"  
  16.         android:allowBackup="true"  
  17.         android:icon="@drawable/ic_launcher"  
  18.         android:label="@string/app_name"  
  19.         android:theme="@style/AppTheme" >  
  20.         <activity  
  21.             android:name=".MainActivity"  
  22.             android:label="@string/app_name" >  
  23.             <intent-filter>  
  24.                 <action android:name="android.intent.action.MAIN" />  
  25.    
  26.                 <category android:name="android.intent.category.LAUNCHER" />  
  27.             </intent-filter>  
  28.         </activity>  
  29.         <activity  
  30.             android:name=".ListOfImages"  
  31.             android:label="Image list" />  
  32.         <activity  
  33.             android:name=".Download"  
  34.             android:label="Download Image" />  
  35.          
  36.     </application>  
  37.    
  38. </manifest>  
Output snapshots:
 
im1f.png
 
Clicking on "Clik here":
 
im2f.png
 
Clicking on any item of the list will download the image to the SD card of the connected phone.
 
im3f.png
 
Thank you