听大牛们说写博客可以提高自己所以来尝试下,由于毕业不久也第一次写,大家见谅见谅!!!不过功能还是完美实现的。
先上GitHub地址:https://github.com/1185719419/DuanDianUP
什么是断点续传呢,简单点理解就是下载一个东西,中途你暂停了或者退出了,下次进来还想继续下载。那要知道哪些东西呢?你第二次下载肯定要知道第一次下载到了什么位置,这样才能从这个地方继续下载。存的话你可以存在本地,那你存的时候也要记录存到了什么位置,下次可以继续往里面存。
具体思路如下:
1.先用线程池开启一个线程获取apk的总长度length,并在本地创建一个长度为length的文件存放。这里存储用RandomAccessFile。
2.再开一个线程下载apk,在这里要用到一个 HttpUrlConnection.setRequestProperty(“Range”,"bytes=0-500")方法:表示的是从文件的0位置开始下载到长度为500位置。
3.设置文件存放位置,从什么地方开始存。
4.记录每一次下载的长度并保存在数据库,由于内容较少我放在了SharedPreferences里面。这个长度就是下次开始下载的位置。
5.当下载完后安装apk,并清除SharedPreferences里面的数据。
1.先用线程池开启一个线程获取apk的总长度length,并在本地创建一个长度为length的文件存放。这里存储用RandomAccessFile。
ExecutorService cacheService = Executors.newCachedThreadPool(); cacheService.execute(new Runnable() { @Override public void run() { HttpURLConnection urlConnection = null; RandomAccessFile randomFile = null; try { URL url = new URL(Utils.MY_URL); urlConnection = (HttpURLConnection) url.openConnection(); urlConnection.setConnectTimeout(3000); urlConnection.setRequestMethod("GET"); int length = -1; if (urlConnection.getResponseCode() == 200) { // 获得文件长度 length = urlConnection.getContentLength(); //创建相同大小的本地文件 File dir = new File(DOWNLOAD_PATH); if (!dir.exists()) { dir.mkdir(); } File file = new File(dir, FILE_NAME); randomFile = new RandomAccessFile(file, "rwd"); randomFile.setLength(length); } if (length <= 0) { return; }else{ Message msg = Message.obtain(); msg.what = length; handler.sendMessage(msg); } } catch (Exception e) { e.printStackTrace(); } finally { // 流的回收逻辑略 } } });
2.再开一个线程下载apk,在这里要用到一个 HttpUrlConnection.setRequestProperty(“Range”,"bytes=0-500")方法:表示的是从文件的0位置开始下载到长度为500位置。
public void run() { super.run(); InputStream inputStream = null; try { URL urls = new URL(Utils.MY_URL); URLConnection rulConnection=urls.openConnection();// HttpURLConnection httConnection = (HttpURLConnection) rulConnection; httConnection.setConnectTimeout(3000); httConnection.setChunkedStreamingMode(0); httConnection.setRequestMethod("GET"); //设置下载位置 int start; httConnection.setRequestProperty("Range", "bytes="+infos.getNow()+"-"+infos.getLength()); httConnection.connect(); int zongLength = infos.getLength(); int nowLength = infos.getNow(); //设置文件存储位置 savePosition(nowLength,zongLength); //保存数据总长度 savaLength(zongLength); if (httConnection.getResponseCode() == 206) { inputStream = httConnection.getInputStream(); byte[] buffer = new byte[512]; int len = -1; long time = System.currentTimeMillis(); while((len = inputStream.read(buffer))!=-1){ randomFile.write(buffer,0,len); int nowLegth = mySharedPreferences.getInt("now", -1)+len; Editor editor = mySharedPreferences.edit(); editor.putString("url",Utils.MY_URL ); editor.putInt("now",nowLegth ); editor.commit(); Message msg = Message.obtain(); float shu = (float)nowLegth/zongLength; DecimalFormat df = new DecimalFormat("0.00");//格式化小数,.后跟几个零代表几位小数 String s = df.format(shu*100);//返回的是String类型 //发送下载百分百 msg.obj = s; handler.sendMessage(msg); if (Utils.zhant) { Editor editor4 = mySharedPreferences.edit(); editor4.putString("now_bfb",s); editor4.commit(); return; } } installApk(); Utils.ones = true; //初始化信息 deleteApkMsg(); } } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }
3.设置文件存放位置,从什么地方开始存。
private void savePosition(int nowLength,int zongLength){ File file=new File(DOWNLOAD_PATH,FILE_NAME); try { randomFile=new RandomAccessFile(file,"rwd"); randomFile.seek(nowLength); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
4.记录每一次下载的长度并保存在数据库,由于内容较少我放在了SharedPreferences里面。这个长度就是下次开始下载的位置。
while((len = inputStream.read(buffer))!=-1){ randomFile.write(buffer,0,len); int nowLegth = mySharedPreferences.getInt("now", -1)+len; Editor editor = mySharedPreferences.edit(); editor.putString("url",Utils.MY_URL ); editor.putInt("now",nowLegth ); editor.commit(); Message msg = Message.obtain(); float shu = (float)nowLegth/zongLength; DecimalFormat df = new DecimalFormat("0.00");//格式化小数,.后跟几个零代表几位小数 String s = df.format(shu*100);//返回的是String类型 //发送下载百分百 msg.obj = s; handler.sendMessage(msg); if (Utils.zhant) { Editor editor4 = mySharedPreferences.edit(); editor4.putString("now_bfb",s); editor4.commit(); return; } }
5.当下载完后安装apk,并清除SharedPreferences里面的数据。
。
/** * 安装apk * */ private void installApk() { File apkfile = new File(DOWNLOAD_PATH, FILE_NAME); if (!apkfile.exists()) { Toast.makeText(context, "apk不存在", Toast.LENGTH_SHORT).show(); return; }else{ } Intent i = new Intent(); i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); i.setAction(Intent.ACTION_VIEW); i.setDataAndType(Uri.parse("file://" + apkfile.toString()), "application/vnd.android.package-archive"); context.startActivity(i); }
/** * 清空数据 * */ private void deleteApkMsg(){ Editor editor = mySharedPreferences.edit(); editor.putString("url",""); editor.putInt("length",0); editor.putInt("start",0); editor.putInt("now",0); editor.commit(); }
代码我就粗略的复制一下了,具体可以在源代码里面看。
下面是别人的微博讲的比我详细:
http://blog.csdn.net/seu_calvin/article/details/53749776