android实现断点续传

    xiaoxiao2021-03-25  95

    代码如下:

    [html]  view plain  copy  print ? package com.example.downloaderstopsart;      import java.util.ArrayList;   import java.util.HashMap;   import java.util.List;   import java.util.Map;      import android.os.Bundle;   import android.os.Handler;   import android.os.Message;   import android.os.StrictMode;   import android.app.ListActivity;   import android.view.View;   import android.widget.LinearLayout;   import android.widget.LinearLayout.LayoutParams;   import android.widget.ProgressBar;   import android.widget.SimpleAdapter;   import android.widget.TextView;   import android.widget.Toast;      public class MainActivity extends ListActivity  {               // 固定下载的资源路径,这里可以设置网络上的地址             private static final String URL = "http://10.81.36.193:8080/";             // 固定存放下载的音乐的路径:SD卡目录下             private static final String SD_PATH = "/mnt/sdcard/";             // 存放各个下载器             private Map<String, Downloader> downloaders = new HashMap<String, Downloader>();             // 存放与下载器对应的进度条             private Map<String, ProgressBar> ProgressBars = new HashMap<String, ProgressBar>();             /**              * 利用消息处理机制适时更新进度条              */             private Handler mHandler = new Handler() {                 public void handleMessage(Message msg) {                     if (msg.what == 1) {                         String url = (String) msg.obj;                         int length = msg.arg1;                         ProgressBar bar = ProgressBars.get(url);                         if (bar != null) {                             // 设置进度条按读取的length长度更新                             bar.incrementProgressBy(length);                             if (bar.getProgress() == bar.getMax()) {                                 Toast.makeText(MainActivity.this, "下载完成!", 0).show();                                 // 下载完成后清除进度条并将map中的数据清空                                 LinearLayout layout = (LinearLayout) bar.getParent();                                 layout.removeView(bar);                                 ProgressBars.remove(url);                                 downloaders.get(url).delete(url);                                 downloaders.get(url).reset();                                 downloaders.remove(url);                             }                         }                     }                 }             };             @Override             public void onCreate(Bundle savedInstanceState) {                 super.onCreate(savedInstanceState);                 setContentView(R.layout.activity_main);                 showListView();                 StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().detectDiskReads().detectDiskWrites().detectNetwork().penaltyLog().build());                 StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectLeakedSqlLiteObjects().detectLeakedClosableObjects().penaltyLog().penaltyDeath().build());             }             // 显示listView,这里可以随便添加音乐             private void showListView() {                 List<Map<String, String>> data = new ArrayList<Map<String, String>>();                 Map<String, String> map = new HashMap<String, String>();                 map.put("name", "mm.mp3");                 data.add(map);                 map = new HashMap<String, String>();                 map.put("name", "pp.mp3");                 data.add(map);                 map = new HashMap<String, String>();                 map.put("name", "tt.mp3");                 data.add(map);                 map = new HashMap<String, String>();                 map.put("name", "ou.mp3");                 data.add(map);                 SimpleAdapter adapter = new SimpleAdapter(this, data, R.layout.list_item, new String[] { "name" },                         new int[] { R.id.tv_resouce_name });                 setListAdapter(adapter);             }             /**              * 响应开始下载按钮的点击事件              */             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());                    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();            }        }   DBHelper:

    [html]  view plain  copy  print ? package com.example.downloaderstopsart;      import android.content.Context;   import android.database.sqlite.SQLiteDatabase;   import android.database.sqlite.SQLiteOpenHelper;      /**    * 建立一个数据库帮助类    */   public class DBHelper extends SQLiteOpenHelper {       // download.db-->数据库名       public DBHelper(Context context) {           super(context, "download.db", null, 1);       }          /**        * 在download.db数据库下创建一个download_info表存储下载信息        */       @Override       public void onCreate(SQLiteDatabase db) {           db.execSQL("create table download_info(_id integer PRIMARY KEY AUTOINCREMENT, thread_id integer, "                   + "start_pos integer, end_pos integer, compelete_size integer,url char)");       }          @Override       public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {          }      }  

    [html]  view plain  copy  print ? DownloadInfo:   [html]  view plain  copy  print ? package com.example.downloaderstopsart;      public class DownloadInfo {       private int threadId;// 下载器id       private int startPos;// 开始点       private int endPos;// 结束点       private int compeleteSize;// 完成度       private String url;// 下载器网络标识          public DownloadInfo(int threadId, int startPos, int endPos,               int compeleteSize, String url) {           this.threadId = threadId;           this.startPos = startPos;           this.endPos = endPos;           this.compeleteSize = compeleteSize;           this.url = url;       }          public DownloadInfo() {       }          public String getUrl() {           return url;       }          public void setUrl(String url) {           this.url = url;       }          public int getThreadId() {           return threadId;       }          public void setThreadId(int threadId) {           this.threadId = threadId;       }          public int getStartPos() {           return startPos;       }          public void setStartPos(int startPos) {           this.startPos = startPos;       }          public int getEndPos() {           return endPos;       }          public void setEndPos(int endPos) {           this.endPos = endPos;       }          public int getCompeleteSize() {           return compeleteSize;       }          public void setCompeleteSize(int compeleteSize) {           this.compeleteSize = compeleteSize;       }          @Override       public String toString() {           return "DownloadInfo [threadId=" + threadId + "startPos=" + startPos                   + ", endPos=" + endPos + "compeleteSize=" + compeleteSize                   + "]";       }   }   LoadInfo:

    [html]  view plain  copy  print ? package com.example.downloaderstopsart;      public class LoadInfo {       public int fileSize;// 文件大小       private int complete;// 完成度       private String urlstring;// 下载器标识          public LoadInfo(int fileSize, int complete, String urlstring) {           this.fileSize = fileSize;           this.complete = complete;           this.urlstring = urlstring;       }          public LoadInfo() {       }          public int getFileSize() {           return fileSize;       }          public void setFileSize(int fileSize) {           this.fileSize = fileSize;       }          public int getComplete() {           return complete;       }          public void setComplete(int complete) {           this.complete = complete;       }          public String getUrlstring() {           return urlstring;       }          public void setUrlstring(String urlstring) {           this.urlstring = urlstring;       }          @Override       public String toString() {           return "LoadInfo [fileSize=" + fileSize + "complete=" + complete                   + ", urlstring=" + urlstring + "]";       }   }   Downloader:

    [html]  view plain  copy  print ? package com.example.downloaderstopsart;   import java.io.File;   import java.io.InputStream;    import java.io.RandomAccessFile;    import java.net.HttpURLConnection;    import java.net.URL;    import java.util.ArrayList;    import java.util.List;    import android.content.Context;    import android.os.Handler;    import android.os.Message;    import android.util.Log;       public class Downloader {        private String urlstr;// 下载的地址        private String localfile;// 保存路径        private int threadcount;// 线程数        private Handler mHandler;// 消息处理器        private Dao dao;// 工具类        private int fileSize;// 所要下载的文件的大小        private List<DownloadInfo> infos;// 存放下载信息类的集合        private static final int INIT = 1;//定义三种下载的状态:初始化状态,正在下载状态,暂停状态        private static final int DOWNLOADING = 2;        private static final int PAUSE = 3;        private int state = INIT;           public Downloader(String urlstr, String localfile, int threadcount,                Context context, Handler mHandler) {            this.urlstr = urlstr;            this.localfile = localfile;            this.threadcount = threadcount;            this.mHandler = mHandler;            dao = new Dao(context);        }        /**         *判断是否正在下载         */        public boolean isdownloading() {            return state == DOWNLOADING;        }        /**         * 得到downloader里的信息         * 首先进行判断是否是第一次下载,如果是第一次就要进行初始化,并将下载器的信息保存到数据库中         * 如果不是第一次下载,那就要从数据库中读出之前下载的信息(起始位置,结束为止,文件大小等),并将下载信息返回给下载器         */        public LoadInfo getDownloaderInfors() {            if (isFirst(urlstr)) {                Log.v("TAG", "isFirst");                init();                int range = fileSize / threadcount;                infos = new ArrayList<DownloadInfo>();                for (int i = 0; i < threadcount - 1; i++) {                    DownloadInfo info = new DownloadInfo(i, i * range, (i + 1)* range - 1, 0, urlstr);                    infos.add(info);                }                DownloadInfo info = new DownloadInfo(threadcount - 1,(threadcount - 1) * range, fileSize - 1, 0, urlstr);                infos.add(info);                //保存infos中的数据到数据库                dao.saveInfos(infos);                //创建一个LoadInfo对象记载下载器的具体信息                LoadInfo loadInfo = new LoadInfo(fileSize, 0, urlstr);                return loadInfo;            } else {                //得到数据库中已有的urlstr的下载器的具体信息                infos = dao.getInfos(urlstr);                Log.v("TAG", "not isFirst size=" + infos.size());                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);        }           /**         * 利用线程开始下载数据         */        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);                    Log.i("RG", "connection--->>>"+connection);                    // 将要下载的文件写到保存在保存路径下的文件中                    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:

    [html]  view plain  copy  print ? package com.example.downloaderstopsart;      import java.util.ArrayList;   import java.util.List;   import android.content.Context;   import android.database.Cursor;   import android.database.sqlite.SQLiteDatabase;      public class Dao {       private DBHelper dbHelper;          public Dao(Context context) {           dbHelper = new DBHelper(context);       }          /**        * 查看数据库中是否有数据        */       public boolean isHasInfors(String urlstr) {           SQLiteDatabase database = dbHelper.getReadableDatabase();           String sql = "select count(*)  from download_info where url=?";           Cursor cursor = database.rawQuery(sql, new String[] { urlstr });           cursor.moveToFirst();           int count = cursor.getInt(0);           cursor.close();           return count == 0;       }          /**        * 36 * 保存 下载的具体信息 37        */       public void saveInfos(List<DownloadInfo> infos) {           SQLiteDatabase database = dbHelper.getWritableDatabase();           for (DownloadInfo info : infos) {               String sql = "insert into download_info(thread_id,start_pos, end_pos,compelete_size,url) values (?,?,?,?,?)";               Object[] bindArgs = { info.getThreadId(), info.getStartPos(),                       info.getEndPos(), info.getCompeleteSize(), info.getUrl() };               database.execSQL(sql, bindArgs);           }       }          /**        * 得到下载具体信息        */       public List<DownloadInfo> getInfos(String urlstr) {           List<DownloadInfo> list = new ArrayList<DownloadInfo>();           SQLiteDatabase database = dbHelper.getReadableDatabase();           String sql = "select thread_id, start_pos, end_pos,compelete_size,url from download_info where url=?";           Cursor cursor = database.rawQuery(sql, new String[] { urlstr });           while (cursor.moveToNext()) {               DownloadInfo info = new DownloadInfo(cursor.getInt(0),                       cursor.getInt(1), cursor.getInt(2), cursor.getInt(3),                       cursor.getString(4));               list.add(info);           }           cursor.close();           return list;       }          /**        * 更新数据库中的下载信息        */       public void updataInfos(int threadId, int compeleteSize, String urlstr) {           SQLiteDatabase database = dbHelper.getReadableDatabase();           String sql = "update download_info set compelete_size=? where thread_id=? and url=?";           Object[] bindArgs = { compeleteSize, threadId, urlstr };           database.execSQL(sql, bindArgs);       }          /**        * 关闭数据库        */       public void closeDb() {           dbHelper.close();       }          /**        * 下载完成后删除数据库中的数据        */       public void delete(String url) {           SQLiteDatabase database = dbHelper.getReadableDatabase();           database.delete("download_info", "url=?", new String[] { url });           database.close();       }   }   xml如下:

    [html]  view plain  copy  print ? <?xml version="1.0" encoding="utf-8"?>     <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"         android:orientation="vertical"         android:layout_width="fill_parent"         android:layout_height="fill_parent"         android:id="@+id/llRoot">         <ListView android:id="@android:id/list"             android:layout_width="fill_parent"             android:layout_height="fill_parent">        </ListView>    </LinearLayout>       item_list.xml:

    [html]  view plain  copy  print ? <?xml version="1.0" encoding="utf-8"?>   <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"       android:layout_width="fill_parent"       android:layout_height="wrap_content"       android:orientation="vertical" >          <LinearLayout           android:layout_width="fill_parent"           android:layout_height="wrap_content"           android:layout_marginBottom="5dip"           android:orientation="horizontal" >              <TextView               android:id="@+id/tv_resouce_name"               android:layout_width="fill_parent"               android:layout_height="wrap_content"               android:layout_weight="1" />              <Button               android:id="@+id/btn_start"               android:layout_width="fill_parent"               android:layout_height="wrap_content"               android:layout_weight="1"               android:onClick="startDownload"               android:text="下载" />              <Button               android:id="@+id/btn_pause"               android:layout_width="fill_parent"               android:layout_height="wrap_content"               android:layout_weight="1"               android:onClick="pauseDownload"               android:text="暂停" />       </LinearLayout>      </LinearLayout>   记得加权限: [html]  view plain  copy  print ? <uses-permission android:name="android.permission.INTERNET"/>    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>   还有在3.0以上的版本记得加上这句话: [html]  view plain  copy  print ? StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().detectDiskReads().detectDiskWrites().detectNetwork().penaltyLog().build());             StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectLeakedSqlLiteObjects().detectLeakedClosableObjects().penaltyLog().penaltyDeath().build());  

    转载请注明原文地址: https://ju.6miu.com/read-14276.html

    最新回复(0)