接着上一篇的http://www.cnblogs.com/zhengxt/p/3657833.html,当我们想给自己的APP写一个文件下载器时,可以用重写IntentService来实现。
使用IntentService有几个好处,IntentService继承于Service,适合拿来处理一些耗时又不需要去管它的任务。把要执行的任务用Intent加入到队列中,IntentService会有一个工作线程来取出队列中的Intent来处理。需要实现抽象方法onHandleIntent方法来执行这些任务。当所有任务都完成后,IntentService会自动停止。
同时使用Notification在通知栏让用户直观的知道下载进度,推荐使用Android3.0(API11)后提供的Notification.Builder来构建Notification。我这里为了让程序兼容Android2.1-2.3就没有使用Notification.Builder,用被废弃的Notification(int,
CharSequence, long)来构建Notification。
还是按照上一篇一样,假设这是个版本更新文件的下载器,当更新文件下载完成后自动弹出安装界面。
IntentService代码:
1 public class DownloadFileService extends IntentService {
2 private static final String TAG = DownloadFileService.class.getSimpleName();
3 public DownloadFileService() {
4 super("com.test.download");
5 }
6
7 private NotificationManager notificationManager;
8 private Notification notification;
9 private RemoteViews rViews;
10 protected void onHandleIntent(Intent intent) {
11 Bundle bundle = intent.getExtras();
12 // 获得下载文件的url
13 String downloadUrl = bundle.getString("url");
14 // 设置文件下载后的保存路径,保存在SD卡根目录的Download文件夹
15 File dirs = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Download");
16 // 检查文件夹是否存在,不存在则创建
17 if (!dirs.exists()) {
18 dirs.mkdir();
19 }
20 File file = new File(dirs, "file.apk");
21 // 设置Notification
22 notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
23 notification = new Notification(R.drawable.ic_launcher, "版本更新下载", System.currentTimeMillis());
24 Intent intentNotifi = new Intent(this, Main.class);
25 PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intentNotifi, 0);
26 notification.contentIntent = pendingIntent;
27 // 加载Notification的布局文件
28 rViews = new RemoteViews(getPackageName(), R.layout.downloadfile_layout);
29 // 设置下载进度条
30 rViews.setProgressBar(R.id.downloadFile_pb, 100, 0, false);
31 notification.contentView = rViews;
32 notificationManager.notify(0, notification);
33 // 开始下载
34 downloadFile(downloadUrl, file);
35 // 移除通知栏
36 notificationManager.cancel(0);
37 // 广播出去,由广播接收器来处理下载完成的文件
38 Intent sendIntent = new Intent("com.test.downloadComplete");
39 // 把下载好的文件的保存地址加进Intent
40 sendIntent.putExtra("downloadFile", file.getPath());
41 sendBroadcast(sendIntent);
42 }
43 private int fileLength, downloadLength;
44 private void downloadFile(String downloadUrl, File file){
45 FileOutputStream fos = null;
46 try {
47 fos = new FileOutputStream(file);
48 } catch (FileNotFoundException e) {
49 Log.e(TAG, "找不到保存下载文件的目录");
50 e.printStackTrace();
51 }
52 InputStream ips = null;
53 try {
54 URL url = new URL(downloadUrl);
55 HttpURLConnection huc = (HttpURLConnection) url.openConnection();
56 huc.setRequestMethod("GET");
57 huc.setReadTimeout(10000);
58 huc.setConnectTimeout(3000);
59 fileLength = Integer.valueOf(huc.getHeaderField("Content-Length"));
60 ips = huc.getInputStream();
61 // 拿到服务器返回的响应码
62 int hand = huc.getResponseCode();
63 if (hand == 200) {
64 // 开始检查下载进度
65 handler.post(run);
66 // 建立一个byte数组作为缓冲区,等下把读取到的数据储存在这个数组
67 byte[] buffer = new byte[8192];
68 int len = 0;
69 while ((len = ips.read(buffer)) != -1) {
70 fos.write(buffer, 0, len);
71 downloadLength = downloadLength + len;
72 }
73 } else {
74 Log.e(TAG, "服务器返回码" + hand);
75 }
76
77 } catch (ProtocolException e) {
78 e.printStackTrace();
79 } catch (MalformedURLException e) {
80 e.printStackTrace();
81 } catch (IOException e) {
82 e.printStackTrace();
83 } finally {
84 try {
85 if (fos != null) {
86 fos.close();
87 }
88 if (ips != null) {
89 ips.close();
90 }
91 } catch (IOException e) {
92 e.printStackTrace();
93 }
94 }
95 }
96
97
98
99 public void onDestroy() {
100 // 移除定時器
101 handler.removeCallbacks(run);
102 super.onDestroy();
103 }
104
105 // 定时器,每隔一段时间检查下载进度,然后更新Notification上的ProgressBar
106 private Handler handler = new Handler();
107 private Runnable run = new Runnable() {
108 public void run() {
109 rViews.setProgressBar(R.id.downloadFile_pb, 100, downloadLength*100 / fileLength, false);
110 notification.contentView = rViews;
111 notificationManager.notify(0, notification);
112 handler.postDelayed(run, 1000);
113 }
114 };
115
116 }
还要记得要在AndroidManifest.xml的application节点里注册Service。例如这样:
1 <service android:name="com.saetest.DownloadFileService"></service>
我们下载个谷歌地图来试试看。
1 public void onClick(View v) {
2 // new CheckedUpdate().execute();
3 String url = "http://www.appchina.com/market/d/1603385/cop.baidu_0/com.google.android.apps.maps.apk";
4 Intent downloadIntent = new Intent(this, DownloadFileService.class);
5 Bundle bundle = new Bundle();
6 bundle.putString("url", url);
7 downloadIntent.putExtras(bundle);
8 startService(downloadIntent);
9 // 设置广播接收器,当新版本的apk下载完成后自动弹出安装界面
10 IntentFilter intentFilter = new IntentFilter("com.test.downloadComplete");
11 receiver = new BroadcastReceiver() {
12
13 public void onReceive(Context context, Intent intent) {
14 Intent install = new Intent(Intent.ACTION_VIEW);
15 String pathString = intent.getStringExtra("downloadFile");
16 install.setDataAndType(Uri.fromFile(new File(pathString)), "application/vnd.android.package-archive");
17 install.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
18 context.startActivity(install);
19 }
20 };
21 registerReceiver(receiver, intentFilter);
22 }
23
24 protected void onDestroy() {
25 // 移除广播接收器
26 if (receiver != null) {
27 unregisterReceiver(receiver);
28 }
29 super.onDestroy();
30 }
使用IntentService给自己的Android应用写一个文件下载器。,码迷,mamicode.com
时间: 2024-12-26 13:45:29