Android did include an API called DownloadManager
for just this purpose...but it was release in 2.3; so while it won't be useful in your application targeting 2.2, it might still be a good resource for you to research the implementation.
A simple implementation I would recommend is something like this:
- Use an
HttpURLConnection
to connect and download the data. This will require the INTERNET permission to be declared in your manifest
- Determine where you want the file to be. If you want it on the device's SD card, you will also need the WRITE_EXTERNAL_STORAGE permission.
- Wrap this operation in the doInBackground() method of an
AsyncTask
. This is a long-running operation, so you need to put it into a background thread, which AsyncTask manages for you.
- Implement this in a
Service
so the operation can run protected without the user keeping the an Activity in the foreground.
- Use
NotificationManager
to notify the user when the download is complete, which will post a message to their status bar.
To simplify things further, if you use IntentService
, it will handle the threading for you (everything in onHandleIntent
gets called on a background thread) and you can queue up multiple downloads for it to handle one at a time by simply sending multiple Intents to it. Here's a skeleton example of what I'm saying:
public class DownloadService extends IntentService {
public static final String EXTRA_URL = "extra_url";
public static final int NOTE_ID = 100;
public DownloadService() {
super("DownloadService");
}
@Override
protected void onHandleIntent(Intent intent) {
if(!intent.hasExtra(EXTRA_URL)) {
//This Intent doesn't have anything for us
return;
}
String url = intent.getStringExtra(EXTRA_URL);
boolean result = false;
try {
URL url = new URL(params[0]);
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
//Input stream from the connection
InputStream in = new BufferedInputStream(connection.getInputStream());
//Output stream to a file in your application's private space
FileOutputStream out = openFileOutput("filename", Activity.MODE_PRIVATE);
//Read and write the stream data here
result = true;
} catch (Exception e) {
e.printStackTrace();
}
//Post a notification once complete
NotificationManager manager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
Notification note;
if(result) {
note = new Notification(0, "Download Complete", System.currentTimeMillis());
} else {
note = new Notification(0, "Download Failed", System.currentTimeMillis());
}
manager.notify(NOTE_ID, note);
}
}
Then you can call this service with the URL you want to download anywhere in an Activity like this:
Intent intent = new Intent(this, DownloadService.class);
intent.putExtra(DownloadService.EXTRA_URL,"http://your.url.here");
startService(intent);
Hope that is helpful!
EDIT: I'm fixing this example to remove the unnecessary double-threading for anyone who comes upon this later.