[Android实例] Android之断点续传上载
[Android实例] Android之断点续传下载LinearLayout xmlns:androidhttp://schemas.android.com/apk/res/
[Android实例] Android之断点续传下载
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"? ? ? ? android:orientation="vertical" android:layout_width="fill_parent"? ? ? ? android:layout_height="fill_parent" android:weightSum="1">? ? ? ? <ListView android:id="@android:id/list" android:layout_height="wrap_content"? ? ? ? ? ? ? ? android:layout_width="match_parent" android:layout_weight="0.70"></ListView></LinearLayout>复制代码list_item.xml:? ? ? ? android:layout_width="fill_parent" android:orientation="vertical">? ? ? ? <LinearLayout android:layout_width="fill_parent"? ? ? ? ? ? ? ? android:id="@+id/linearLayout2" android:layout_height="wrap_content"? ? ? ? ? ? ? ? android:orientation="horizontal" android:layout_marginBottom="5dip">? ? ? ? ? ? ? ? <TextView android:layout_width="fill_parent"? ? ? ? ? ? ? ? ? ? ? ? android:layout_height="wrap_content" android:layout_weight="1"? ? ? ? ? ? ? ? ? ? ? ? android:id="@+id/tv_resouce_name" />? ? ? ? ? ? ? ? <Button android:layout_width="fill_parent"? ? ? ? ? ? ? ? ? ? ? ? android:layout_height="wrap_content" android:layout_weight="1"? ? ? ? ? ? ? ? ? ? ? ? android:text="下载" android:id="@+id/btn_start" android:onClick="startDownload" />? ? ? ? ? ? ? ? <Button android:layout_width="fill_parent"? ? ? ? ? ? ? ? ? ? ? ? android:layout_height="wrap_content" android:layout_weight="1"? ? ? ? ? ? ? ? ? ? ? ? android:text="暂停" android:id="@+id/btn_pause" android:onClick="pauseDownload" />? ? ? ? </LinearLayout></LinearLayout>复制代码我们要定义一个记录在下载时各个时期的数据的类,这里我创建了一个DownloadInfo类来记录。代码如下:
DownloadInfo:? ? ? ?? ?? ?? ?? ?? ?? ?+ ", startPos=" + startPos + ", endPos=" + endPos? ? ? ?? ?? ?? ?? ?? ?? ?+ ", compeleteSize=" + compeleteSize +"]";? ???}}复制代码在下载时,我们有进度条来显示进度,怎么确定进度条的进度,大小和起始位置呢?这里我定义了一个LoadInfo类来记录下载器详细信息。代码如下:
LoadInfo:? ? ? ?? ?? ?? ?? ?? ?? ?+ ", urlstring=" + urlstring + "]";? ???}}复制代码下面是最最重要的一步,那就是定义一个下载器来进行下载了,这里我就不多说,具体解释在代码中都有注解,供大家研究参考。
Downloader:? ? ? ? ? ? ? ? ? ? ? ? int size = 0;? ? ? ? ? ? ? ? ? ? ? ? int compeleteSize = 0;? ? ? ? ? ? ? ? ? ? ? ? for (DownloadInfo info : infos) {? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? compeleteSize += info.getCompeleteSize();? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? size += info.getEndPos() - info.getStartPos() + 1;? ? ? ? ? ? ? ? ? ? ? ? }? ? ? ? ? ? ? ? ? ? ? ? return new LoadInfo(size, compeleteSize, urlstr);? ? ? ? ? ? ? ? }? ? ? ? }? ? ? ? /**? ?? ?*/? ? ? ? private void init() {? ? ? ? ? ? ? ? try {? ? ? ? ? ? ? ? ? ? ? ? URL url = new URL(urlstr);? ? ? ? ? ? ? ? ? ? ? ? HttpURLConnection connection = (HttpURLConnection) url? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? .openConnection();? ? ? ? ? ? ? ? ? ? ? ? connection.setConnectTimeout(5000);? ? ? ? ? ? ? ? ? ? ? ? connection.setRequestMethod("GET");? ? ? ? ? ? ? ? ? ? ? ? fileSize = connection.getContentLength();? ? ? ? ? ? ? ? ? ? ? ? File file = new File(localfile);? ? ? ? ? ? ? ? ? ? ? ? if (!file.exists()) {? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? file.createNewFile();? ? ? ? ? ? ? ? ? ? ? ? }? ? ? ? ? ? ? ? ? ? ? ? // 本地访问文件? ? ? ? ? ? ? ? ? ? ? ? RandomAccessFile accessFile = new RandomAccessFile(file, "rwd");? ? ? ? ? ? ? ? ? ? ? ? accessFile.setLength(fileSize);? ? ? ? ? ? ? ? ? ? ? ? accessFile.close();? ? ? ? ? ? ? ? ? ? ? ? connection.disconnect();? ? ? ? ? ? ? ? } catch (Exception e) {? ? ? ? ? ? ? ? ? ? ? ? e.printStackTrace();? ? ? ? ? ? ? ? }? ? ? ? }? ? ? ? /**? ? ? ???* 判断是否是第一次 下载? ? ? ???*/? ? ? ? private boolean isFirst(String urlstr) {? ? ? ? ? ? ? ? return dao.isHasInfors(urlstr);? ? ? ? }? ? ? ? /**? ? ? ???* 114 * 利用线程开始下载数据 115? ? ? ???*/? ? ? ? public void download() {? ? ? ? ? ? ? ? if (infos != null) {? ? ? ? ? ? ? ? ? ? ? ? if (state == DOWNLOADING)? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? return;? ? ? ? ? ? ? ? ? ? ? ? state = DOWNLOADING;? ? ? ? ? ? ? ? ? ? ? ? for (DownloadInfo info : infos) {? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? new MyThread(info.getThreadId(), info.getStartPos(),? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? info.getEndPos(), info.getCompeleteSize(),? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? info.getUrl()).start();? ? ? ? ? ? ? ? ? ? ? ? }? ? ? ? ? ? ? ? }? ? ? ? }? ? ? ? public class MyThread extends Thread {? ? ? ? ? ? ? ? private int threadId;? ? ? ? ? ? ? ? private int startPos;? ? ? ? ? ? ? ? private int endPos;? ? ? ? ? ? ? ? private int compeleteSize;? ? ? ? ? ? ? ? private String urlstr;? ? ? ? ? ? ? ? public MyThread(int threadId, int startPos, int endPos,? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? int compeleteSize, String urlstr) {? ? ? ? ? ? ? ? ? ? ? ? this.threadId = threadId;? ? ? ? ? ? ? ? ? ? ? ? this.startPos = startPos;? ? ? ? ? ? ? ? ? ? ? ? this.endPos = endPos;? ? ? ? ? ? ? ? ? ? ? ? this.compeleteSize = compeleteSize;? ? ? ? ? ? ? ? ? ? ? ? this.urlstr = urlstr;? ? ? ? ? ? ? ? }? ? ? ? ? ? ? ? @Override? ? ? ? ? ? ? ? public void run() {? ? ? ? ? ? ? ? ? ? ? ? HttpURLConnection connection = null;? ? ? ? ? ? ? ? ? ? ? ? RandomAccessFile randomAccessFile = null;? ? ? ? ? ? ? ? ? ? ? ? InputStream is = null;? ? ? ? ? ? ? ? ? ? ? ? try {? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? URL url = new URL(urlstr);? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? connection = (HttpURLConnection) url.openConnection();? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? connection.setConnectTimeout(5000);? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? connection.setRequestMethod("GET");? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 设置范围,格式为Range:bytes x-y;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? connection.setRequestProperty("Range", "bytes="? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? + (startPos + compeleteSize) + "-" + endPos);? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? randomAccessFile = new RandomAccessFile(localfile, "rwd");? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? randomAccessFile.seek(startPos + compeleteSize);? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 将要下载的文件写到保存在保存路径下的文件中? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? is = connection.getInputStream();? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? byte[] buffer = new byte[4096];? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? int length = -1;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? while ((length = is.read(buffer)) != -1) {? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? randomAccessFile.write(buffer, 0, length);? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? compeleteSize += length;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 更新数据库中的下载信息? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? dao.updataInfos(threadId, compeleteSize, urlstr);? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 用消息将下载信息传给进度条,对进度条进行更新? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Message message = Message.obtain();? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? message.what = 1;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? message.obj = urlstr;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? message.arg1 = length;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? mHandler.sendMessage(message);? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? if (state == PAUSE) {? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? return;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }? ? ? ? ? ? ? ? ? ? ? ? } catch (Exception e) {? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? e.printStackTrace();? ? ? ? ? ? ? ? ? ? ? ? } finally {? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? try {? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? is.close();? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? randomAccessFile.close();? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? connection.disconnect();? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? dao.closeDb();? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? } catch (Exception e) {? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? e.printStackTrace();? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }? ? ? ? ? ? ? ? ? ? ? ? }? ? ? ? ? ? ? ? }? ? ? ? }? ? ? ? // 删除数据库中urlstr对应的下载器信息? ? ? ? public void delete(String urlstr) {? ? ? ? ? ? ? ? dao.delete(urlstr);? ? ? ? }? ? ? ? // 设置暂停? ? ? ? public void pause() {? ? ? ? ? ? ? ? state = PAUSE;? ? ? ? }? ? ? ? // 重置下载状态? ? ? ? public void reset() {? ? ? ? ? ? ? ? state = INIT;? ? ? ? }}复制代码在这边下载器类的定义中,我们用到了许多关于进行数据库操作的方法,这里我定义了一个数据库工具类,来提供这些方法,代码如下:
Dao:? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? new int[] { R.id.tv_resouce_name });? ? ? ? ? ? ? ? setListAdapter(adapter);? ? ? ? }? ? ? ? /**? ? ? ???* 83 * 响应开始下载按钮的点击事件 84? ? ? ???*/? ? ? ? public void startDownload(View v) {? ? ? ? ? ? ? ? // 得到textView的内容? ? ? ? ? ? ? ? LinearLayout layout = (LinearLayout) v.getParent();? ? ? ? ? ? ? ? String musicName = ((TextView) layout? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? .findViewById(R.id.tv_resouce_name)).getText().toString();? ? ? ? ? ? ? ? String urlstr = URL + musicName;? ? ? ? ? ? ? ? String localfile = SD_PATH + musicName;? ? ? ? ? ? ? ? // 设置下载线程数为4,这里是我为了方便随便固定的? ? ? ? ? ? ? ? int threadcount = 4;? ? ? ? ? ? ? ? // 初始化一个downloader下载器? ? ? ? ? ? ? ? Downloader downloader = downloaders.get(urlstr);? ? ? ? ? ? ? ? if (downloader == null) {? ? ? ? ? ? ? ? ? ? ? ? downloader = new Downloader(urlstr, localfile, threadcount, this,? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? mHandler);? ? ? ? ? ? ? ? ? ? ? ? downloaders.put(urlstr, downloader);? ? ? ? ? ? ? ? }? ? ? ? ? ? ? ? if (downloader.isdownloading())? ? ? ? ? ? ? ? ? ? ? ? return;? ? ? ? ? ? ? ? // 得到下载信息类的个数组成集合? ? ? ? ? ? ? ? LoadInfo loadInfo = downloader.getDownloaderInfors();? ? ? ? ? ? ? ? // 显示进度条? ? ? ? ? ? ? ? showProgress(loadInfo, urlstr, v);? ? ? ? ? ? ? ? // 调用方法开始下载? ? ? ? ? ? ? ? downloader.download();? ? ? ? }? ? ? ? /**? ? ? ???* 显示进度条? ? ? ???*/? ? ? ? private void showProgress(LoadInfo loadInfo, String url, View v) {? ? ? ? ? ? ? ? ProgressBar bar = ProgressBars.get(url);? ? ? ? ? ? ? ? if (bar == null) {? ? ? ? ? ? ? ? ? ? ? ? bar = new ProgressBar(this, null,? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? android.R.attr.progressBarStyleHorizontal);? ? ? ? ? ? ? ? ? ? ? ? bar.setMax(loadInfo.getFileSize());? ? ? ? ? ? ? ? ? ? ? ? bar.setProgress(loadInfo.getComplete());? ? ? ? ? ? ? ? ? ? ? ? System.out.println(loadInfo.getFileSize()+"--"+loadInfo.getComplete());? ? ? ? ? ? ? ? ? ? ? ? ProgressBars.put(url, bar);? ? ? ? ? ? ? ? ? ? ? ? LinearLayout.LayoutParams params = new LayoutParams(? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? LayoutParams.FILL_PARENT, 5);? ? ? ? ? ? ? ? ? ? ? ? ((LinearLayout) ((LinearLayout) v.getParent()).getParent())? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? .addView(bar, params);? ? ? ? ? ? ? ? }? ? ? ? }? ? ? ? /**? ? ? ???* 响应暂停下载按钮的点击事件? ? ? ???*/? ? ? ? public void pauseDownload(View v) {? ? ? ? ? ? ? ? LinearLayout layout = (LinearLayout) v.getParent();? ? ? ? ? ? ? ? String musicName = ((TextView) layout? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? .findViewById(R.id.tv_resouce_name)).getText().toString();? ? ? ? ? ? ? ? String urlstr = URL + musicName;? ? ? ? ? ? ? ? downloaders.get(urlstr).pause();? ? ? ? }}复制代码最后我们需要在android Manifest.xml中添加这两个权限一个是访问internet的权限,另一个是写外存的权限。- <uses-permission android:name="android.permission.INTERNET"></uses-permission>
- ? ? <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
复制代码最后运行的效果图:
万事俱备只欠东风啦!哈哈,我需要在我的web工程里放几个音乐文件。
下载后得到的文件可在sdcard下面找到!