Android开发之断点续传(下载)
程序员文章站
2022-05-03 18:00:18
downloadutils
public class downloadutils {
private static final string tag = "downloadutil...
downloadutils
public class downloadutils { private static final string tag = "downloadutils"; private static volatile downloadutils instance; private file file; private string filepath; private okhttpclient client; private file downloadfile; private long startposition; private call call; private downloadutils() { client = new okhttpclient(); } private downloadlistener listener; public void setlistener(downloadlistener listener) { this.listener = listener; } /** * 初始化下载父路径 * * @param path */ public void initdownload(string path) { file = new file(path); if (!file.getparentfile().exists()) { file.getparentfile().mkdir(); } if (!file.exists()) { file.mkdir(); } filepath = file.getabsolutepath(); log.i(tag, "initdownload: " + filepath); } public static downloadutils getinstance() { if (null == instance) { synchronized (downloadutils.class) { if (instance == null) { instance = new downloadutils(); } } } return instance; } public void startdownload(string url) { if (textutils.isempty(url)) { return; } if (url.contains(".")) { string typename = url.substring(url.lastindexof(".") + 1); if (url.contains("/")) { string name = url.substring(url.lastindexof("/") + 1, url.lastindexof(".")); string fn = name + "." + typename; downloadfile = new file(file, fn); } } startposition = 0; if (downloadfile.exists()) { startposition = downloadfile.length(); } request request = new request.builder() .addheader("range", "bytes=" + startposition + "-") .url(url) .build(); call = client.newcall(request); call.enqueue(new callback() { @override public void onfailure(call call, ioexception e) { } @override public void onresponse(call call, response response) throws ioexception { listener.startdownload(); responsebody body = response.body(); long totallength = body.contentlength() + startposition; log.i(tag, "totallength: " + totallength + "----"); inputstream is = body.bytestream(); byte[] buf = new byte[2048]; int length = 0; long totalnum = startposition; randomaccessfile raf = new randomaccessfile(downloadfile, "rw"); raf.seek(totalnum); while ((length = is.read(buf, 0, buf.length)) != -1) { raf.write(buf, 0, length); totalnum += length; listener.downloadprogress(totalnum * 100 / totallength); } log.i(tag, "totalnum==" + totalnum + "---"); listener.finishdownload(downloadfile.getabsolutepath()); body.close(); } }); } public void pausedownload() { listener.pausedownload(); if (call != null && call.isexecuted()) { call.cancel(); } } }
downloadlistener
public interface downloadlistener { void startdownload(); void pausedownload(); void finishdownload(string path); void downloadprogress(long progress); }
mainactivity
public class mainactivity extends appcompatactivity implements view.onclicklistener { private textview tv_pro; private progressbar progressbar; private button btn_start; private button btn_pause; private string downloadurl = "https://acj3.pc6.com/pc6_soure/2017-12/com.yek.android.kfc.activitys_3820.apk"; @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); tv_pro = findviewbyid(r.id.tv_pro); progressbar = findviewbyid(r.id.progressbar); btn_start = findviewbyid(r.id.start); btn_pause = findviewbyid(r.id.pause); btn_start.setonclicklistener(this); btn_pause.setonclicklistener(this); if (environment.getexternalstoragestate().equals(environment.media_mounted)) { file storagedirectory = environment.getexternalstoragedirectory(); string absolutepath = storagedirectory.getabsolutepath(); final string path = absolutepath + "/download/"; log.i("zzz", "下载路径 " + path); downloadutils.getinstance().initdownload(path); downloadutils.getinstance().setlistener(new downloadlistener() { @override public void startdownload() { } @override public void pausedownload() { } @override public void finishdownload(string path) { installapk(new file(path)); } @override public void downloadprogress(final long progress) { runonuithread(new runnable() { @override public void run() { tv_pro.settext((int)progress + "%"); progressbar.setprogress((int) progress); } }); } }); } } @override public void onclick(view view) { switch (view.getid()) { case r.id.start: downloadutils.getinstance().startdownload(downloadurl); break; case r.id.pause: downloadutils.getinstance().pausedownload(); break; } } /** * 安装apk * * @param file */ private void installapk(file file) { intent intent = new intent(); intent.setaction(intent.action_view); intent.addcategory("android.intent.category.default"); intent.addflags(intent.flag_activity_new_task); intent.setdataandtype(uri.fromfile(file), "application/vnd.android.package-archive"); startactivity(intent); android.os.process.killprocess(android.os.process.mypid()); } }
activity_main.xml
推荐阅读
-
Android开发之自定义刮刮卡实现代码
-
RxJava+Retrofit+OkHttp实现多文件下载之断点续传
-
Android开发实现高仿优酷的客户端图片左右滑动切换功能实例【附源码下载】
-
Android开发之菜单(menu)用法实例分析
-
Android开发笔记之:如何屏蔽Button setClickable与setEnabled
-
Android开发笔记之:复写按钮方法
-
Android开发笔记之:如何安全中止一个自定义线程Thread的方法
-
Android开发笔记之:Log图文详解(Log.v,Log.d,Log.i,Log.w,Log.e)
-
Android开发笔记之:在ImageView上绘制圆环的实现方法
-
Android开发笔记之:返回键的复写onBackPressed()介绍