1. 创建HttpURLConnection对象
2.获得一个InputStream对象
3.修改权限:访问网络和写SDK卡,在Manifest.xml声明:
<uses-permission android:name="android.permission.INTERNET"/> //允许网络访问 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> //允许写入SDK卡
String urlDownload = ""; urlDownload = "http://www.baidu.com/img/baidu_sylogo1.gif"; URL url = new URL(urlDownload ); // 打开连接 URLConnection con = url.openConnection(); // 输入流 InputStream is = con.getInputStream();
如上面的代码所示,指定一个下载的目标链接,我们上面指定了一个图片地址。然后构建一个URL对象,调用该 对象的openConnection方法来建立一个数据通路(连接)。代码的最后一行使用 con.getInputStream,拿到一个输入流对象,通过这个流对象我们就可以读取到这个文件的内容了。下面要做的,就是读取这个流,将流写入我 们的本地文件。不过在这之前,我们还要说下这个方法:
//获得文件的长度 int contentLength = con.getContentLength(); System.out.println("长度 :"+contentLength);
获得文件长度的方法。ContentLength是不很熟啊。它是http协议里描述头(head)部分的描述属性之一。实际这里是发送了一个http请求,分析了返回(response)里数据内容。
我们常常会把文件下载到手机的存储卡里,所以还会用到获得存储卡路径的方法:
// 获得存储卡路径,构成 保存文件的目标路径 String dirName = ""; dirName = Environment.getExternalStorageDirectory()+"/MyDownload/"; File f = new File(dirName); if(!f.exists()) { f.mkdir(); }
Environment.getExternalStorageDirectory() 方法会返回一个字符串,指示了存储卡的路径。我们拼接字符串出一个准备存放下载文件的文件夹。并先判断文件夹是是否存在,如果不存在,则新建一个文件夹。
做完了上面的准备后,基本就能实现下载了。我们看看主要的完整代码。
下载前的准备工作:
//要下载的文件路径 String urlDownload = ""; //urlDownload = "http://192.168.3.39/text.txt"; urlDownload = "http://www.baidu.com/img/baidu_sylogo1.gif"; // 获得存储卡路径,构成 保存文件的目标路径 String dirName = ""; dirName = Environment.getExternalStorageDirectory()+"/MyDownload/"; File f = new File(dirName); if(!f.exists()) { f.mkdir(); }
下载的操作:
//准备拼接新的文件名(保存在存储卡后的文件名) String newFilename = _urlStr.substring(_urlStr.lastIndexOf("/")+1); newFilename = _dirName + newFilename; File file = new File(newFilename); //如果目标文件已经存在,则删除。产生覆盖旧文件的效果 if(file.exists()) { file.delete(); } try { // 构造URL URL url = new URL(_urlStr); // 打开连接 URLConnection con = url.openConnection(); //获得文件的长度 int contentLength = con.getContentLength(); System.out.println("长度 :"+contentLength); // 输入流 InputStream is = con.getInputStream(); // 1K的数据缓冲 byte[] bs = new byte[1024]; // 读取到的数据长度 int len; // 输出的文件流 OutputStream os = new FileOutputStream(newFilename); // 开始读取 while ((len = is.read(bs)) != -1) { os.write(bs, 0, len); } // 完毕,关闭所有链接 os.close(); is.close(); } catch (Exception e) { e.printStackTrace(); }
下面是封装的一些方法我的部分代码如下:
//从服务器下载图片到本地 private void getPhotoFromServer(List<Advert> adverts){ //读取服务器ip地址 String serverip = NetworkUtil.getDns(); //直接读取服务器的ip地址 //String serverURL = serverURLAll.substring(serverURLAll.indexOf(":")+3, serverURLAll.lastIndexOf(":")); //最好还是直接从数据库或者其他地方读取ip地址 Log.d(TAG, "server ip is " + serverip); //整合成完整的广告图片存放地址目录 String urlDownload = "http://" + serverip +":8080/proPicRecord/"; //广告图片本地sd卡存放目录 String dirName = "/sdcard/advert/"; //判断本地存放广告图片的目录是否存,不存在则新建文件夹 File f = new File(dirName); if(!f.exists()) { f.mkdir(); } //服务器上广告图片完整路径名,供下载用 String urlDownloadAll = ""; //准备拼接新的文件名(保存在存储卡后的文件名) for(int i=0; adverts!=null && i<adverts.size(); i++){ Advert advert = adverts.get(i); //下载路径添加上广告图片名字 urlDownloadAll = urlDownload + advert.getUrl(); Log.d(TAG, "The whole server download url is " + urlDownloadAll); //获取广告图片的名字,其实使用advert.getUrl()也可 String newFilename = urlDownloadAll.substring(urlDownloadAll.lastIndexOf("/")+1); //本地播放广告图片的完整路径 newFilename = dirName + newFilename; Log.d(TAG, "The local url is" + newFilename); File file = new File(newFilename); //如果目标文件已经存在,则删除,产生覆盖旧文件的效果(此处以后可以扩展为已经存在图片不再重新下载功能) if(file.exists()) { file.delete(); } try{ //构造URL URL url = new URL(urlDownloadAll); //打开连接 URLConnection con = url.openConnection(); //获得文件的长度 //int contentLength = con.getContentLength(); //System.out.println("长度 :"+contentLength); //输入流 InputStream is = con.getInputStream(); //1K的数据缓冲 byte[] bs = new byte[1024]; //读取到的数据长度 int len; //输出的文件流 OutputStream os = new FileOutputStream(newFilename); //开始读取 while ((len = is.read(bs)) != -1) { os.write(bs, 0, len); } //完毕,关闭所有链接 os.close(); is.close(); }catch(Exception e){ e.printStackTrace(); } } }
单个文件下载:
package page.util; import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; public class HttpDownloaderUtil{ private URL url=null; /** * 根据URL下载文本文件,以行读取文件 */ public String download(String urlStr){ StringBuffer sb = new StringBuffer(); String line = null; BufferedReader buffer = null; try{ url = new URL(urlStr); HttpURLConnection urlConn = (HttpURLConnection)url.openConnection(); buffer = new BufferedReader(new InputStreamReader(urlConn.getInputStream())); while((line = buffer.readLine())!=null) { sb.append(line); } }catch(Exception e) { e.printStackTrace(); }finally{ try{ buffer.close(); }catch(Exception e){ e.printStackTrace(); } } return sb.toString(); } /** * 下载文件并写SD卡 * @param urlStr * @param path * @param fileName * @return 0-success,-1-fail,1-existed */ public int downFile(String urlStr,String path,String fileName){ InputStream inputStream= null; try{ FileUtil fileUtil = new FileUtil(); if(fileUtil.isFileExist(path+fileName)) return 1; else{ inputStream = getInputStreamFromUrl(urlStr); File resultFile = fileUtil.write2SDFromInput(path, fileName, inputStream); if(resultFile == null) return -1; } }catch(Exception e){ e.printStackTrace(); }finally{ try{ inputStream.close(); }catch(Exception e){ e.printStackTrace(); } } return 0; } public InputStream getInputStreamFromUrl(String urlStr) throws MalformedURLException,IOException{ url = new URL(urlStr); HttpURLConnection urlCon =(HttpURLConnection)url.openConnection(); InputStream inputStream = urlCon.getInputStream(); return inputStream; } }
文件处理的工具类:
package page.util; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import android.os.Environment; public class FileUtil{ private String SDPATH; public String getSDPATH(){ return SDPATH; } public FileUtil(){ SDPATH= Environment.getExternalStorageDirectory()+"/"; } public File createSDFile(String fileName) throws IOException{ File file = new File(SDPATH+fileName); file.createNewFile(); return file; } public File createSDDir(String dirName) { File dir = new File(SDPATH+dirName); dir.mkdir(); return dir; } public boolean isFileExist(String fileName){ File file = new File(SDPATH+fileName); return file.exists(); } public File write2SDFromInput(String path,String fileName,InputStream input){ File file = null; OutputStream output = null; try{ createSDDir(path); file = createSDFile(path+fileName); output = new FileOutputStream(file); byte buffer[] = new byte[4*1024]; while((input.read(buffer))!=-1){ output.write(buffer); } output.flush(); }catch(Exception e){ e.printStackTrace(); }finally{ try{ output.close(); } catch(Exception e){ e.printStackTrace(); } } return file; } }
DownLoaderTask.java
package com.johnny.testzipanddownload; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; import android.app.ProgressDialog; import android.content.Context; import android.content.DialogInterface; import android.content.DialogInterface.OnCancelListener; import android.os.AsyncTask; import android.util.Log; public class DownLoaderTask extends AsyncTask<Void, Integer, Long> { private final String TAG = "DownLoaderTask"; private URL mUrl; private File mFile; private ProgressDialog mDialog; private int mProgress = 0; private ProgressReportingOutputStream mOutputStream; private Context mContext; public DownLoaderTask(String url,String out,Context context){ super(); if(context!=null){ mDialog = new ProgressDialog(context); mContext = context; } else{ mDialog = null; } try { mUrl = new URL(url); String fileName = new File(mUrl.getFile()).getName(); mFile = new File(out, fileName); Log.d(TAG, "out="+out+", name="+fileName+",mUrl.getFile()="+mUrl.getFile()); } catch (MalformedURLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } @Override protected void onPreExecute() { // TODO Auto-generated method stub //super.onPreExecute(); if(mDialog!=null){ mDialog.setTitle("Downloading..."); mDialog.setMessage(mFile.getName()); mDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); mDialog.setOnCancelListener(new OnCancelListener() { @Override public void onCancel(DialogInterface dialog) { // TODO Auto-generated method stub cancel(true); } }); mDialog.show(); } } @Override protected Long doInBackground(Void... params) { // TODO Auto-generated method stub return download(); } @Override protected void onProgressUpdate(Integer... values) { // TODO Auto-generated method stub //super.onProgressUpdate(values); if(mDialog==null) return; if(values.length>1){ int contentLength = values[1]; if(contentLength==-1){ mDialog.setIndeterminate(true); } else{ mDialog.setMax(contentLength); } } else{ mDialog.setProgress(values[0].intValue()); } } @Override protected void onPostExecute(Long result) { // TODO Auto-generated method stub //super.onPostExecute(result); if(mDialog!=null&&mDialog.isShowing()){ mDialog.dismiss(); } if(isCancelled()) return; ((MainActivity)mContext).showUnzipDialog(); } private long download(){ URLConnection connection = null; int bytesCopied = 0; try { connection = mUrl.openConnection(); int length = connection.getContentLength(); if(mFile.exists()&&length == mFile.length()){ Log.d(TAG, "file "+mFile.getName()+" already exits!!"); return 0l; } mOutputStream = new ProgressReportingOutputStream(mFile); publishProgress(0,length); bytesCopied =copy(connection.getInputStream(),mOutputStream); if(bytesCopied!=length&&length!=-1){ Log.e(TAG, "Download incomplete bytesCopied="+bytesCopied+", length"+length); } mOutputStream.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return bytesCopied; } private int copy(InputStream input, OutputStream output){ byte[] buffer = new byte[1024*8]; BufferedInputStream in = new BufferedInputStream(input, 1024*8); BufferedOutputStream out = new BufferedOutputStream(output, 1024*8); int count =0,n=0; try { while((n=in.read(buffer, 0, 1024*8))!=-1){ out.write(buffer, 0, n); count+=n; } out.flush(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ try { out.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } try { in.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } return count; } private final class ProgressReportingOutputStream extends FileOutputStream{ public ProgressReportingOutputStream(File file) throws FileNotFoundException { super(file); // TODO Auto-generated constructor stub } @Override public void write(byte[] buffer, int byteOffset, int byteCount) throws IOException { // TODO Auto-generated method stub super.write(buffer, byteOffset, byteCount); mProgress += byteCount; publishProgress(mProgress); } } }
解压:
ZipExtractorTask .java
package com.johnny.testzipanddownload; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Enumeration; import java.util.zip.ZipEntry; import java.util.zip.ZipException; import java.util.zip.ZipFile; import android.app.ProgressDialog; import android.content.Context; import android.content.DialogInterface; import android.content.DialogInterface.OnCancelListener; import android.os.AsyncTask; import android.util.Log; public class ZipExtractorTask extends AsyncTask<Void, Integer, Long> { private final String TAG = "ZipExtractorTask"; private final File mInput; private final File mOutput; private final ProgressDialog mDialog; private int mProgress = 0; private final Context mContext; private boolean mReplaceAll; public ZipExtractorTask(String in, String out, Context context, boolean replaceAll){ super(); mInput = new File(in); mOutput = new File(out); if(!mOutput.exists()){ if(!mOutput.mkdirs()){ Log.e(TAG, "Failed to make directories:"+mOutput.getAbsolutePath()); } } if(context!=null){ mDialog = new ProgressDialog(context); } else{ mDialog = null; } mContext = context; mReplaceAll = replaceAll; } @Override protected Long doInBackground(Void... params) { // TODO Auto-generated method stub return unzip(); } @Override protected void onPostExecute(Long result) { // TODO Auto-generated method stub //super.onPostExecute(result); if(mDialog!=null&&mDialog.isShowing()){ mDialog.dismiss(); } if(isCancelled()) return; } @Override protected void onPreExecute() { // TODO Auto-generated method stub //super.onPreExecute(); if(mDialog!=null){ mDialog.setTitle("Extracting"); mDialog.setMessage(mInput.getName()); mDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); mDialog.setOnCancelListener(new OnCancelListener() { @Override public void onCancel(DialogInterface dialog) { // TODO Auto-generated method stub cancel(true); } }); mDialog.show(); } } @Override protected void onProgressUpdate(Integer... values) { // TODO Auto-generated method stub //super.onProgressUpdate(values); if(mDialog==null) return; if(values.length>1){ int max=values[1]; mDialog.setMax(max); } else mDialog.setProgress(values[0].intValue()); } private long unzip(){ long extractedSize = 0L; Enumeration<ZipEntry> entries; ZipFile zip = null; try { zip = new ZipFile(mInput); long uncompressedSize = getOriginalSize(zip); publishProgress(0, (int) uncompressedSize); entries = (Enumeration<ZipEntry>) zip.entries(); while(entries.hasMoreElements()){ ZipEntry entry = entries.nextElement(); if(entry.isDirectory()){ continue; } File destination = new File(mOutput, entry.getName()); if(!destination.getParentFile().exists()){ Log.e(TAG, "make="+destination.getParentFile().getAbsolutePath()); destination.getParentFile().mkdirs(); } if(destination.exists()&&mContext!=null&&!mReplaceAll){ } ProgressReportingOutputStream outStream = new ProgressReportingOutputStream(destination); extractedSize+=copy(zip.getInputStream(entry),outStream); outStream.close(); } } catch (ZipException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ try { zip.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } return extractedSize; } private long getOriginalSize(ZipFile file){ Enumeration<ZipEntry> entries = (Enumeration<ZipEntry>) file.entries(); long originalSize = 0l; while(entries.hasMoreElements()){ ZipEntry entry = entries.nextElement(); if(entry.getSize()>=0){ originalSize+=entry.getSize(); } } return originalSize; } private int copy(InputStream input, OutputStream output){ byte[] buffer = new byte[1024*8]; BufferedInputStream in = new BufferedInputStream(input, 1024*8); BufferedOutputStream out = new BufferedOutputStream(output, 1024*8); int count =0,n=0; try { while((n=in.read(buffer, 0, 1024*8))!=-1){ out.write(buffer, 0, n); count+=n; } out.flush(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ try { out.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } try { in.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } return count; } private final class ProgressReportingOutputStream extends FileOutputStream{ public ProgressReportingOutputStream(File file) throws FileNotFoundException { super(file); // TODO Auto-generated constructor stub } @Override public void write(byte[] buffer, int byteOffset, int byteCount) throws IOException { // TODO Auto-generated method stub super.write(buffer, byteOffset, byteCount); mProgress += byteCount; publishProgress(mProgress); } } }
MainActivity.java
package com.johnny.testzipanddownload; import android.os.Bundle; import android.os.Environment; import android.app.Activity; import android.app.AlertDialog; import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; import android.util.Log; import android.view.Menu; public class MainActivity extends Activity { private final String TAG="MainActivity"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Log.d(TAG, "Environment.getExternalStorageDirectory()="+Environment.getExternalStorageDirectory()); Log.d(TAG, "getCacheDir().getAbsolutePath()="+getCacheDir().getAbsolutePath()); showDownLoadDialog(); //doZipExtractorWork(); //doDownLoadWork(); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } private void showDownLoadDialog(){ new AlertDialog.Builder(this).setTitle("确认") .setMessage("是否下载?") .setPositiveButton("是", new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // TODO Auto-generated method stub Log.d(TAG, "onClick 1 = "+which); doDownLoadWork(); } }) .setNegativeButton("否", new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // TODO Auto-generated method stub Log.d(TAG, "onClick 2 = "+which); } }) .show(); } public void showUnzipDialog(){ new AlertDialog.Builder(this).setTitle("确认") .setMessage("是否解压?") .setPositiveButton("是", new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // TODO Auto-generated method stub Log.d(TAG, "onClick 1 = "+which); doZipExtractorWork(); } }) .setNegativeButton("否", new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // TODO Auto-generated method stub Log.d(TAG, "onClick 2 = "+which); } }) .show(); } public void doZipExtractorWork(){ //ZipExtractorTask task = new ZipExtractorTask("/storage/usb3/system.zip", "/storage/emulated/legacy/", this, true); ZipExtractorTask task = new ZipExtractorTask("/storage/emulated/legacy/testzip.zip", "/storage/emulated/legacy/", this, true); task.execute(); } private void doDownLoadWork(){ DownLoaderTask task = new DownLoaderTask("http://192.168.9.155/johnny/testzip.zip", "/storage/emulated/legacy/", this); //DownLoaderTask task = new DownLoaderTask("http://192.168.9.155/johnny/test.h264", getCacheDir().getAbsolutePath()+"/", this); task.execute(); } }