今天遇到了这样的一项任务,就是给定url下载apk文件到指定的位置。
基本上是从网上下载下来代码改一改就可以了,中间遇到了一些小麻烦,下载的时候报异常。
位置为:InputStream is = conn.getInputStream();
获取返回的输入流的时候。
解决方式:
1.用buffered流包装一下。
2.使用HttpURLConnection进行链接并添加头声明
具体解决方法写在类里面了。下面的这个类经过测试可用,下载10M以下的apk文件应该没问题。
当然这种不支持断点下载的方式是很差劲的,虽然给的要求并没有明确提出支持断点下载,但是作为一名开发者还是为未来考虑一下更合适,毕竟这功能以后肯定是会需要的。
大体上的思路也已经了解了,以后有空会写第二个类支持断点下载的。
/** * @author tim_liu */ public class DownLoadOneApp { Context context; private String appname; private String downloadurl; private String outfilepath; //the progress is displayed. public int progress; //the app file size public int fileSize; //means download size public int downLoadFileSize; public DownLoadOneApp(Context context,String outfilepath,String downloadurl) { this.context = context; this.downloadurl=downloadurl; this.outfilepath=outfilepath; this.appname=getAppName(downloadurl); } /** * @param outpath * @param url */ public void startdownfile() { final String downurl=downloadurl; final String outpath=outfilepath+appname; File pathfile=new File(outfilepath); if(!pathfile.exists()){ Log_I("the path "+outfilepath+" is not exists,so we mkdirs it"); if(pathfile.mkdirs()){ Log_I("mkdirs "+outfilepath+" success!"); }else{ Log_I("mkdirs "+outfilepath+" occur error!"); return ; } } new Thread() { public void run() { try { // 下载文件,参数:第一个URL,第二个存放路径 down_file(downurl,outpath); } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }.start(); } /** * download file * @param url * @param path * @throws IOException */ private void down_file(String url, String outpath) throws IOException { // 获取文件名 URL myURL = new URL(url); HttpURLConnection conn = (HttpURLConnection) myURL.openConnection(); conn.setConnectTimeout(5000); conn.setRequestMethod("GET"); conn.setRequestProperty("Accept-Language", "zh-CN"); conn.setRequestProperty("Referer", myURL.toString()); conn.setRequestProperty("Charset", "UTF-8"); conn.setRequestProperty("Connection", "Keep-Alive"); // 设置范围,格式为Range:bytes x-y; conn.connect(); this.fileSize = conn.getContentLength();// 根据响应获取文件大小 // conn.setRequestProperty("RANGE", "bytes=0-"+fileSize); InputStream is = conn.getInputStream(); if (this.fileSize <= 0) throw new RuntimeException("无法获知文件大小 "); if (is == null) throw new RuntimeException("stream is null"); FileOutputStream fos = new FileOutputStream(outpath); BufferedInputStream bis = null; BufferedOutputStream bos = null; bis = new BufferedInputStream(is); bos = new BufferedOutputStream(fos); // 把数据存入路径+文件名 byte buf[] = new byte[4048]; downLoadFileSize = 0; sendMsg(0); do { // 循环读取 int numread = bis.read(buf); if (numread == -1) { break; } bos.write(buf, 0, numread); downLoadFileSize += numread; sendMsg(1);// 更新进度条 } while (true); sendMsg(2);// 通知下载完成 try { is.close(); } catch (Exception ex) { Log_E("error: " + ex.getMessage()); } finally { bis.close(); bos.close(); fos.close(); } } private Handler handler = new Handler() { @Override public void handleMessage(Message msg) {// 定义一个Handler,用于处理下载线程与UI间通讯 if (!Thread.currentThread().isInterrupted()) { //msg.what is flag.if flag is 0 means start download,flag is 1 means update process,flag is 2 is means switch (msg.what) { case 0: Log_I("start download app file"); case 1: progress = downLoadFileSize * 100 / fileSize; Log_I("progress:"+progress); break; case 2: downloadAPPFile(); break; case -1: downloadOccurError(msg.getData().getString("error")); break; } } super.handleMessage(msg); } }; private void sendMsg(int flag) { Message msg = new Message(); msg.what = flag; handler.sendMessage(msg); } private String getAppName(String urlstr){ return urlstr.substring(urlstr.lastIndexOf("/")+1); } private void Log_I(String log) { Log.i("WV_"+this.getClass().getName(), log); } private void Log_E(String log) { Log.e("WV_"+this.getClass().getName(), log); } /** * The following method for the call */ /** * get info about down file size for MB,for example 2.10MB */ public String getFileSizeByMB() { double size = ((double) fileSize / 1024.0) / 1024.0; DecimalFormat df = new DecimalFormat("#####0.00 "); String sizestr = df.format(size); return sizestr; } /** * get info about download size for byte */ public String getdownLoadSize(){ return Integer.toString(downLoadFileSize); } /** * The download is complete */ public void downloadAPPFile(){ Toast.makeText(context, "文件下载完成", Toast.LENGTH_SHORT).show(); } /** * The download process is abnormal */ public void downloadOccurError(String error){ Toast.makeText(context, error, Toast.LENGTH_SHORT).show(); } }