使用后台服务下载文件的例子

最近做了一个DEMO, 是通过httpURLConnection服务来下载文件。 大致的设计思路是这样的:
1. 主Activity,显示需要下载的文件名,并通过ProgressDialog来显示下载进度。
2. 后台服务IntentService进行主要的下载操作,先通过HttpURLConnection来获取远程服务的InputStream, 然后将获取的InputStream写入设备的sdCard中。
3. 通过ResultReceiver传递下载的完成信息给ProgressDialog,使其能及时更新下载进度。

具体的代码:
1. 老样子,在AndroidManifest.xml中设置对因特网的访问权限,和对SDCard的操作权限

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>


2. 其次,需要在AndroidManifest.xml中设置Activity和Service

<activity
android:name="cn.sh.ideal.activity.DownloadActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

<service android:name="cn.sh.ideal.service.DownloadService"/>


3. 在DownloadActivity中,显示需要下载的文件名,点击文件名,调用DownloadService进行文件的下载,并在界面中产生ProgressDialog进度

if(fileRealName!=null && fileRealName.trim().length()>0){

fileName = fileRealName;

try {
url = ToolsUtil.getIpAddress() + URLEncoder.encode(fileRealName,"UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}

progressDialog = new ProgressDialog(DownloadActivity.this);
progressDialog.setTitle(getResources().getString(R.string.download_title));
progressDialog.setMessage(getResources().getString(R.string.download_message));
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);

progressDialog.show();

intent = new Intent(DownloadActivity.this, DownloadService.class);
intent.putExtra("url", url);
intent.putExtra("filename", fileName);
intent.putExtra("receiver", new DownloadReceiver(new Handler()));
intent.setAction("start");
startService(intent);

}


4. DownloadService 对文件进行下载

protected void onHandleIntent(Intent intent) {
String urlToDownload = intent.getStringExtra("url");
String filenameToSave = intent.getStringExtra("filename");

ResultReceiver receiver = (ResultReceiver) intent.getParcelableExtra("receiver");

String sdPath = "";
int results = 0;
String infos = "";

InputStream input = null;
OutputStream output = null;

try {
//设备中是否存在SDCard,如果不存在则抛出异常
isSDCard();
//设备是否可连接,如果不可链接则抛出异常
isConnected();

sdPath = Environment.getExternalStorageDirectory() + "/" + Constants.DOWNLOAD_PATH;
// SDCard中的存储路径是否存在,如果不存在则创建
File dir = new File(sdPath);
if(!dir.exists()) createSDDir(sdPath);

sdPath = Environment.getExternalStorageDirectory() + "/" + Constants.DOWNLOAD_PATH + "/" + filenameToSave;

// 计算需要下载的文件的长度
long totalSize = getRemoteFilesize(urlToDownload);

// 计算SDCard的剩余空间是否足够保存下载文件。如果不够,则抛出异常
isSDCardFreeSizeAvailable((int)totalSize);

URL url = new URL(urlToDownload);
connection = (HttpURLConnection) url.openConnection();
connection.setConnectTimeout(CONNECT_TIME_OUT);

connection.connect();

// 获取Http服务的返回信息,如果服务信息为HTTP_OK, HTTP_PARTIAL, 则可进行下载服务,否则抛出异常
int code = getHttpResponseMessage(connection);
Log.i(TAG,"httpReturnType=" + code);

input = new BufferedInputStream(connection.getInputStream());

output =new FileOutputStream(sdPath);

byte data[] = new byte[1024];
long total = 0l;
int count;
while ((count = input.read(data)) != -1) {
total += count;

Bundle resultData = new Bundle();
resultData.putInt("progress" ,(int) (total * 100 / totalSize));
receiver.send(UPDATE_PROGRESS, resultData);
output.write(data, 0, count);
}

output.flush();
output.close();
input.close();

results = DOWNLOAD_SUCCESS;
}
catch(SDCardNotAvailableException sdex){
results = DOWNLOAD_ERROR;
infos = getResources().getString(R.string.download_error_sdcard_not_available);
}
catch(AndroidNoActiveConnectionException aex){
results = DOWNLOAD_ERROR;
infos = getResources().getString(R.string.download_error_no_active_connection);
}
catch(SDCardFreeNotAvailableException sdfex){
infos = getResources().getString(R.string.download_error_sdcard_not_free);
results = DOWNLOAD_ERROR;
}
catch(HttpServiceException rex){
results = DOWNLOAD_ERROR;
infos = getResources().getString(R.string.download_error_http_service);
}
catch(FileNotFoundException fex){
results = DOWNLOAD_ERROR;
infos = getResources().getString(R.string.download_error_file_not_found);
}catch(IOException ioex){
results = DOWNLOAD_ERROR;
infos = getResources().getString(R.string.download_error_io);
}
catch(Exception ex){
results = DOWNLOAD_ERROR;
infos = getResources().getString(R.string.download_error_others);
Log.e(TAG,ex.getLocalizedMessage());
}
finally{
if(input!=null)
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
if(output!=null)
try {
output.close();
} catch (IOException e) {
e.printStackTrace();
}

if(connection!=null) connection.disconnect();

Bundle resultData = new Bundle();
resultData.putInt("progress" ,results);

if(infos!=null && infos.trim().length()>0)
resultData.putString("resultMessage", infos);

receiver.send(UPDATE_PROGRESS, resultData);
}



5. 在DownloadActivity中添加DownloadReceiver类,用以接收DownloadService的下载进度信息和错误信息

private class DownloadReceiver extends ResultReceiver{
public DownloadReceiver(Handler handler) {
super(handler);
}

protected void onReceiveResult(int resultCode, Bundle resultData) {
super.onReceiveResult(resultCode, resultData);

if (resultCode == DownloadService.UPDATE_PROGRESS) {
int progress = resultData.getInt("progress");

if(progress == DownloadService.DOWNLOAD_ERROR){
String infos = resultData.getString("resultMessage");
progressDialog.dismiss();
Toast.makeText(DownloadActivity.this, infos, Toast.LENGTH_SHORT).show();

}else if(progress == DownloadService.DOWNLOAD_SUCCESS){
progressDialog.dismiss();

}else{
progressDialog.setProgress(progress);
}
}
}


附件中提供了这个DEMO的完整代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值