- 浏览: 4064715 次
文章分类
最新评论
-
klxh:
Android如何一次安装多个apk -
kchiu:
废话啊啊啊
TCP,socket 心跳检测 -
追求幸福:
iOS: 当发生signal 9为 kill的时候,程序直接被 ...
android和iOS平台的崩溃捕获和收集 -
andsy2008:
给的地址,没豆子呢,能单独发一份给我吗,andsy2008@1 ...
点餐订餐系统应用android源码 -
王粤新:
[b][i][u]引用[list]
[*][flash=200 ...
百度地图SDK for Android【事件监听】
Android 断点续传
- packagecom.example.downloaderstopsart;
- importjava.util.ArrayList;
- importjava.util.HashMap;
- importjava.util.List;
- importjava.util.Map;
- importandroid.os.Bundle;
- importandroid.os.Handler;
- importandroid.os.Message;
- importandroid.os.StrictMode;
- importandroid.app.ListActivity;
- importandroid.view.View;
- importandroid.widget.LinearLayout;
- importandroid.widget.LinearLayout.LayoutParams;
- importandroid.widget.ProgressBar;
- importandroid.widget.SimpleAdapter;
- importandroid.widget.TextView;
- importandroid.widget.Toast;
- publicclassMainActivityextendsListActivity{
- //固定下载的资源路径,这里可以设置网络上的地址
- privatestaticfinalStringURL="http://10.81.36.193:8080/";
- //固定存放下载的音乐的路径:SD卡目录下
- privatestaticfinalStringSD_PATH="/mnt/sdcard/";
- //存放各个下载器
- privateMap<String,Downloader>downloaders=newHashMap<String,Downloader>();
- //存放与下载器对应的进度条
- privateMap<String,ProgressBar>ProgressBars=newHashMap<String,ProgressBar>();
- /**
- *利用消息处理机制适时更新进度条
- */
- privateHandlermHandler=newHandler(){
- publicvoidhandleMessage(Messagemsg){
- if(msg.what==1){
- Stringurl=(String)msg.obj;
- intlength=msg.arg1;
- ProgressBarbar=ProgressBars.get(url);
- if(bar!=null){
- //设置进度条按读取的length长度更新
- bar.incrementProgressBy(length);
- if(bar.getProgress()==bar.getMax()){
- Toast.makeText(MainActivity.this,"下载完成!",0).show();
- //下载完成后清除进度条并将map中的数据清空
- LinearLayoutlayout=(LinearLayout)bar.getParent();
- layout.removeView(bar);
- ProgressBars.remove(url);
- downloaders.get(url).delete(url);
- downloaders.get(url).reset();
- downloaders.remove(url);
- }
- }
- }
- }
- };
- @Override
- publicvoidonCreate(BundlesavedInstanceState){
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- showListView();
- StrictMode.setThreadPolicy(newStrictMode.ThreadPolicy.Builder().detectDiskReads().detectDiskWrites().detectNetwork().penaltyLog().build());
- StrictMode.setVmPolicy(newStrictMode.VmPolicy.Builder().detectLeakedSqlLiteObjects().detectLeakedClosableObjects().penaltyLog().penaltyDeath().build());
- }
- //显示listView,这里可以随便添加音乐
- privatevoidshowListView(){
- List<Map<String,String>>data=newArrayList<Map<String,String>>();
- Map<String,String>map=newHashMap<String,String>();
- map.put("name","mm.mp3");
- data.add(map);
- map=newHashMap<String,String>();
- map.put("name","pp.mp3");
- data.add(map);
- map=newHashMap<String,String>();
- map.put("name","tt.mp3");
- data.add(map);
- map=newHashMap<String,String>();
- map.put("name","ou.mp3");
- data.add(map);
- SimpleAdapteradapter=newSimpleAdapter(this,data,R.layout.list_item,newString[]{"name"},
- newint[]{R.id.tv_resouce_name});
- setListAdapter(adapter);
- }
- /**
- *响应开始下载按钮的点击事件
- */
- publicvoidstartDownload(Viewv){
- //得到textView的内容
- LinearLayoutlayout=(LinearLayout)v.getParent();
- StringmusicName=((TextView)layout.findViewById(R.id.tv_resouce_name)).getText().toString();
- Stringurlstr=URL+musicName;
- Stringlocalfile=SD_PATH+musicName;
- //设置下载线程数为4,这里是我为了方便随便固定的
- intthreadcount=4;
- //初始化一个downloader下载器
- Downloaderdownloader=downloaders.get(urlstr);
- if(downloader==null){
- downloader=newDownloader(urlstr,localfile,threadcount,this,mHandler);
- downloaders.put(urlstr,downloader);
- }
- if(downloader.isdownloading())
- return;
- //得到下载信息类的个数组成集合
- LoadInfoloadInfo=downloader.getDownloaderInfors();
- //显示进度条
- showProgress(loadInfo,urlstr,v);
- //调用方法开始下载
- downloader.download();
- }
- /**
- *显示进度条
- */
- privatevoidshowProgress(LoadInfoloadInfo,Stringurl,Viewv){
- ProgressBarbar=ProgressBars.get(url);
- if(bar==null){
- bar=newProgressBar(this,null,android.R.attr.progressBarStyleHorizontal);
- bar.setMax(loadInfo.getFileSize());
- bar.setProgress(loadInfo.getComplete());
- ProgressBars.put(url,bar);
- LinearLayout.LayoutParamsparams=newLayoutParams(LayoutParams.FILL_PARENT,5);
- ((LinearLayout)((LinearLayout)v.getParent()).getParent()).addView(bar,params);
- }
- }
- /**
- *响应暂停下载按钮的点击事件
- */
- publicvoidpauseDownload(Viewv){
- LinearLayoutlayout=(LinearLayout)v.getParent();
- StringmusicName=((TextView)layout.findViewById(R.id.tv_resouce_name)).getText().toString();
- Stringurlstr=URL+musicName;
- downloaders.get(urlstr).pause();
- }
- }
DBHelper:
- packagecom.example.downloaderstopsart;
- importandroid.content.Context;
- importandroid.database.sqlite.SQLiteDatabase;
- importandroid.database.sqlite.SQLiteOpenHelper;
- /**
- *建立一个数据库帮助类
- */
- publicclassDBHelperextendsSQLiteOpenHelper{
- //download.db-->数据库名
- publicDBHelper(Contextcontext){
- super(context,"download.db",null,1);
- }
- /**
- *在download.db数据库下创建一个download_info表存储下载信息
- */
- @Override
- publicvoidonCreate(SQLiteDatabasedb){
- db.execSQL("createtabledownload_info(_idintegerPRIMARYKEYAUTOINCREMENT,thread_idinteger,"
- +"start_posinteger,end_posinteger,compelete_sizeinteger,urlchar)");
- }
- @Override
- publicvoidonUpgrade(SQLiteDatabasedb,intoldVersion,intnewVersion){
- }
- }
- DownloadInfo:
- packagecom.example.downloaderstopsart;
- publicclassDownloadInfo{
- privateintthreadId;//下载器id
- privateintstartPos;//开始点
- privateintendPos;//结束点
- privateintcompeleteSize;//完成度
- privateStringurl;//下载器网络标识
- publicDownloadInfo(intthreadId,intstartPos,intendPos,
- intcompeleteSize,Stringurl){
- this.threadId=threadId;
- this.startPos=startPos;
- this.endPos=endPos;
- this.compeleteSize=compeleteSize;
- this.url=url;
- }
- publicDownloadInfo(){
- }
- publicStringgetUrl(){
- returnurl;
- }
- publicvoidsetUrl(Stringurl){
- this.url=url;
- }
- publicintgetThreadId(){
- returnthreadId;
- }
- publicvoidsetThreadId(intthreadId){
- this.threadId=threadId;
- }
- publicintgetStartPos(){
- returnstartPos;
- }
- publicvoidsetStartPos(intstartPos){
- this.startPos=startPos;
- }
- publicintgetEndPos(){
- returnendPos;
- }
- publicvoidsetEndPos(intendPos){
- this.endPos=endPos;
- }
- publicintgetCompeleteSize(){
- returncompeleteSize;
- }
- publicvoidsetCompeleteSize(intcompeleteSize){
- this.compeleteSize=compeleteSize;
- }
- @Override
- publicStringtoString(){
- return"DownloadInfo[threadId="+threadId+",startPos="+startPos
- +",endPos="+endPos+",compeleteSize="+compeleteSize
- +"]";
- }
- }
LoadInfo:
- packagecom.example.downloaderstopsart;
- publicclassLoadInfo{
- publicintfileSize;//文件大小
- privateintcomplete;//完成度
- privateStringurlstring;//下载器标识
- publicLoadInfo(intfileSize,intcomplete,Stringurlstring){
- this.fileSize=fileSize;
- this.complete=complete;
- this.urlstring=urlstring;
- }
- publicLoadInfo(){
- }
- publicintgetFileSize(){
- returnfileSize;
- }
- publicvoidsetFileSize(intfileSize){
- this.fileSize=fileSize;
- }
- publicintgetComplete(){
- returncomplete;
- }
- publicvoidsetComplete(intcomplete){
- this.complete=complete;
- }
- publicStringgetUrlstring(){
- returnurlstring;
- }
- publicvoidsetUrlstring(Stringurlstring){
- this.urlstring=urlstring;
- }
- @Override
- publicStringtoString(){
- return"LoadInfo[fileSize="+fileSize+",complete="+complete
- +",urlstring="+urlstring+"]";
- }
- }
Downloader:
- packagecom.example.downloaderstopsart;
- importjava.io.File;
- importjava.io.InputStream;
- importjava.io.RandomAccessFile;
- importjava.net.HttpURLConnection;
- importjava.net.URL;
- importjava.util.ArrayList;
- importjava.util.List;
- importandroid.content.Context;
- importandroid.os.Handler;
- importandroid.os.Message;
- importandroid.util.Log;
- publicclassDownloader{
- privateStringurlstr;//下载的地址
- privateStringlocalfile;//保存路径
- privateintthreadcount;//线程数
- privateHandlermHandler;//消息处理器
- privateDaodao;//工具类
- privateintfileSize;//所要下载的文件的大小
- privateList<DownloadInfo>infos;//存放下载信息类的集合
- privatestaticfinalintINIT=1;//定义三种下载的状态:初始化状态,正在下载状态,暂停状态
- privatestaticfinalintDOWNLOADING=2;
- privatestaticfinalintPAUSE=3;
- privateintstate=INIT;
- publicDownloader(Stringurlstr,Stringlocalfile,intthreadcount,
- Contextcontext,HandlermHandler){
- this.urlstr=urlstr;
- this.localfile=localfile;
- this.threadcount=threadcount;
- this.mHandler=mHandler;
- dao=newDao(context);
- }
- /**
- *判断是否正在下载
- */
- publicbooleanisdownloading(){
- returnstate==DOWNLOADING;
- }
- /**
- *得到downloader里的信息
- *首先进行判断是否是第一次下载,如果是第一次就要进行初始化,并将下载器的信息保存到数据库中
- *如果不是第一次下载,那就要从数据库中读出之前下载的信息(起始位置,结束为止,文件大小等),并将下载信息返回给下载器
- */
- publicLoadInfogetDownloaderInfors(){
- if(isFirst(urlstr)){
- Log.v("TAG","isFirst");
- init();
- intrange=fileSize/threadcount;
- infos=newArrayList<DownloadInfo>();
- for(inti=0;i<threadcount-1;i++){
- DownloadInfoinfo=newDownloadInfo(i,i*range,(i+1)*range-1,0,urlstr);
- infos.add(info);
- }
- DownloadInfoinfo=newDownloadInfo(threadcount-1,(threadcount-1)*range,fileSize-1,0,urlstr);
- infos.add(info);
- //保存infos中的数据到数据库
- dao.saveInfos(infos);
- //创建一个LoadInfo对象记载下载器的具体信息
- LoadInfoloadInfo=newLoadInfo(fileSize,0,urlstr);
- returnloadInfo;
- }else{
- //得到数据库中已有的urlstr的下载器的具体信息
- infos=dao.getInfos(urlstr);
- Log.v("TAG","notisFirstsize="+infos.size());
- intsize=0;
- intcompeleteSize=0;
- for(DownloadInfoinfo:infos){
- compeleteSize+=info.getCompeleteSize();
- size+=info.getEndPos()-info.getStartPos()+1;
- }
- returnnewLoadInfo(size,compeleteSize,urlstr);
- }
- }
- /**
- *初始化
- */
- privatevoidinit(){
- try{
- URLurl=newURL(urlstr);
- HttpURLConnectionconnection=(HttpURLConnection)url.openConnection();
- connection.setConnectTimeout(5000);
- connection.setRequestMethod("GET");
- fileSize=connection.getContentLength();
- Filefile=newFile(localfile);
- if(!file.exists()){
- file.createNewFile();
- }
- //本地访问文件
- RandomAccessFileaccessFile=newRandomAccessFile(file,"rwd");
- accessFile.setLength(fileSize);
- accessFile.close();
- connection.disconnect();
- }catch(Exceptione){
- e.printStackTrace();
- }
- }
- /**
- *判断是否是第一次下载
- */
- privatebooleanisFirst(Stringurlstr){
- returndao.isHasInfors(urlstr);
- }
- /**
- *利用线程开始下载数据
- */
- publicvoiddownload(){
- if(infos!=null){
- if(state==DOWNLOADING)
- return;
- state=DOWNLOADING;
- for(DownloadInfoinfo:infos){
- newMyThread(info.getThreadId(),info.getStartPos(),
- info.getEndPos(),info.getCompeleteSize(),
- info.getUrl()).start();
- }
- }
- }
- publicclassMyThreadextendsThread{
- privateintthreadId;
- privateintstartPos;
- privateintendPos;
- privateintcompeleteSize;
- privateStringurlstr;
- publicMyThread(intthreadId,intstartPos,intendPos,
- intcompeleteSize,Stringurlstr){
- this.threadId=threadId;
- this.startPos=startPos;
- this.endPos=endPos;
- this.compeleteSize=compeleteSize;
- this.urlstr=urlstr;
- }
- @Override
- publicvoidrun(){
- HttpURLConnectionconnection=null;
- RandomAccessFilerandomAccessFile=null;
- InputStreamis=null;
- try{
- URLurl=newURL(urlstr);
- connection=(HttpURLConnection)url.openConnection();
- connection.setConnectTimeout(5000);
- connection.setRequestMethod("GET");
- //设置范围,格式为Range:bytesx-y;
- connection.setRequestProperty("Range","bytes="+(startPos+compeleteSize)+"-"+endPos);
- randomAccessFile=newRandomAccessFile(localfile,"rwd");
- randomAccessFile.seek(startPos+compeleteSize);
- Log.i("RG","connection--->>>"+connection);
- //将要下载的文件写到保存在保存路径下的文件中
- is=connection.getInputStream();
- byte[]buffer=newbyte[4096];
- intlength=-1;
- while((length=is.read(buffer))!=-1){
- randomAccessFile.write(buffer,0,length);
- compeleteSize+=length;
- //更新数据库中的下载信息
- dao.updataInfos(threadId,compeleteSize,urlstr);
- //用消息将下载信息传给进度条,对进度条进行更新
- Messagemessage=Message.obtain();
- message.what=1;
- message.obj=urlstr;
- message.arg1=length;
- mHandler.sendMessage(message);
- if(state==PAUSE){
- return;
- }
- }
- }catch(Exceptione){
- e.printStackTrace();
- }finally{
- try{
- is.close();
- randomAccessFile.close();
- connection.disconnect();
- dao.closeDb();
- }catch(Exceptione){
- e.printStackTrace();
- }
- }
- }
- }
- //删除数据库中urlstr对应的下载器信息
- publicvoiddelete(Stringurlstr){
- dao.delete(urlstr);
- }
- //设置暂停
- publicvoidpause(){
- state=PAUSE;
- }
- //重置下载状态
- publicvoidreset(){
- state=INIT;
- }
- }
Dao:
- packagecom.example.downloaderstopsart;
- importjava.util.ArrayList;
- importjava.util.List;
- importandroid.content.Context;
- importandroid.database.Cursor;
- importandroid.database.sqlite.SQLiteDatabase;
- publicclassDao{
- privateDBHelperdbHelper;
- publicDao(Contextcontext){
- dbHelper=newDBHelper(context);
- }
- /**
- *查看数据库中是否有数据
- */
- publicbooleanisHasInfors(Stringurlstr){
- SQLiteDatabasedatabase=dbHelper.getReadableDatabase();
- Stringsql="selectcount(*)fromdownload_infowhereurl=?";
- Cursorcursor=database.rawQuery(sql,newString[]{urlstr});
- cursor.moveToFirst();
- intcount=cursor.getInt(0);
- cursor.close();
- returncount==0;
- }
- /**
- *36*保存下载的具体信息37
- */
- publicvoidsaveInfos(List<DownloadInfo>infos){
- SQLiteDatabasedatabase=dbHelper.getWritableDatabase();
- for(DownloadInfoinfo:infos){
- Stringsql="insertintodownload_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);
- }
- }
- /**
- *得到下载具体信息
- */
- publicList<DownloadInfo>getInfos(Stringurlstr){
- List<DownloadInfo>list=newArrayList<DownloadInfo>();
- SQLiteDatabasedatabase=dbHelper.getReadableDatabase();
- Stringsql="selectthread_id,start_pos,end_pos,compelete_size,urlfromdownload_infowhereurl=?";
- Cursorcursor=database.rawQuery(sql,newString[]{urlstr});
- while(cursor.moveToNext()){
- DownloadInfoinfo=newDownloadInfo(cursor.getInt(0),
- cursor.getInt(1),cursor.getInt(2),cursor.getInt(3),
- cursor.getString(4));
- list.add(info);
- }
- cursor.close();
- returnlist;
- }
- /**
- *更新数据库中的下载信息
- */
- publicvoidupdataInfos(intthreadId,intcompeleteSize,Stringurlstr){
- SQLiteDatabasedatabase=dbHelper.getReadableDatabase();
- Stringsql="updatedownload_infosetcompelete_size=?wherethread_id=?andurl=?";
- Object[]bindArgs={compeleteSize,threadId,urlstr};
- database.execSQL(sql,bindArgs);
- }
- /**
- *关闭数据库
- */
- publicvoidcloseDb(){
- dbHelper.close();
- }
- /**
- *下载完成后删除数据库中的数据
- */
- publicvoiddelete(Stringurl){
- SQLiteDatabasedatabase=dbHelper.getReadableDatabase();
- database.delete("download_info","url=?",newString[]{url});
- database.close();
- }
- }
xml如下:
- <?xmlversion="1.0"encoding="utf-8"?>
- <LinearLayoutxmlns: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">
- <ListViewandroid:id="@android:id/list"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent">
- </ListView>
- </LinearLayout>
item_list.xml:
- <?xmlversion="1.0"encoding="utf-8"?>
- <LinearLayoutxmlns: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-permissionandroid:name="android.permission.INTERNET"/>
- <uses-permissionandroid:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
还有在3.0以上的版本记得加上这句话:
- StrictMode.setThreadPolicy(newStrictMode.ThreadPolicy.Builder().detectDiskReads().detectDiskWrites().detectNetwork().penaltyLog().build());
- StrictMode.setVmPolicy(newStrictMode.VmPolicy.Builder().detectLeakedSqlLiteObjects().detectLeakedClosableObjects().penaltyLog().penaltyDeath().build());
效果图如下:
相关推荐
android断点续传
android断点续传下载,不因网络错误、空间不足等原因而停止下载,死循环下载,直到手动退出。
该工具类封装了以断点续传方式进行下载的功能。
网络上常用的断点续传下载代码,适合于大文件的下载。
Android断点续传,socket网络编程!
一个适用于android环境的断点续传下载模块,支持暂停、继续。实例中通过几个下载wma音乐文件的例子,来演示android下载内容,并支持暂停、继续的功能,并可在意外断开的情况下,下次打开后继续下载,也就是断点续传...
Android 断点续传 源码 java Demo
http://www.ibm.com/developerworks/cn/java/joy-down/index.html参考文章以上,主要实现在android系统里断点续传下载任意类型的文件....可以在DDMS里查看文件的实际下载进度,可以再LOGCAT里查看系统的Log日志,...
Android中实现断点续传下载功能,有详细的注释,需要的打包带走。
真心收集的 android 断点续传文件实现
android客户端实现断点续传功能,可实现多线程断点续传下载。实现android端断点续传下载需要服务器的支持,本demo中包含了个人写的服务器端的下载功能的demo.
一个实现断点续传的android小demo,帮助理解怎样断点续传下载实现
基于android实现下载网络资源,文件、多媒体等,采用多线程,实现了断点续传。
OKHttp3是如今非常流行的Android网络请求框架,那么如何利用Android实现断点续传呢,今天写了个Demo尝试了一下,感觉还是有点意思 准备阶段 我们会用到OKHttp3来做网络请求,使用RxJava来实现线程的切换,并且开启Java8...