代码如下:

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:

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表存储下载信息 */@Overridepublic 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)");}@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {}}

DownloadInfo:
package com.example.downloaderstopsart;public class DownloadInfo {private int threadId;// 下载器idprivate 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;}@Overridepublic String toString() {return "DownloadInfo [threadId=" + threadId + ", startPos=" + startPos+ ", endPos=" + endPos + ", compeleteSize=" + compeleteSize+ "]";}}

LoadInfo:

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;}@Overridepublic String toString() {return "LoadInfo [fileSize=" + fileSize + ", complete=" + complete+ ", urlstring=" + urlstring + "]";}}

Downloader:

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:

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如下:

<?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:

<?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>

记得加权限:
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

还有在3.0以上的版本记得加上这句话:
 StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().detectDiskReads().detectDiskWrites().detectNetwork().penaltyLog().build());        StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectLeakedSqlLiteObjects().detectLeakedClosableObjects().penaltyLog().penaltyDeath().build());

效果图如下:


更多相关文章

  1. 【Android】logcat日志信息过滤
  2. Android全局异常捕捉
  3. Android登录界面设计1(纯java)
  4. android实现桌面icon未读信息图标
  5. Android课程表界面布局实现
  6. Android(安卓)7.0解析包时出现问题 的解决方案(应用内更新)
  7. 两部android设备通过服务器转发实现通信简单demo
  8. Android学习―7种形式的Android(安卓)Dialog使用举例
  9. Android从捕获全局异常说起

随机推荐

  1. 增加系统最大音量
  2. Android(安卓)Studio插件整理
  3. android之ListView和SimpleAdapter的组合
  4. android之startActivityForResult的使用
  5. 安卓视频通讯与监控系统完全版本正式发布
  6. cordova的android notify消息通知插件
  7. android 开发 GitHub Android(安卓)Libra
  8. android的sdk源码下载地址及关连方法
  9. 写个android下倒计时软件
  10. GreenDao —— 简单快速操作 Android(安