Android开发之文件下载

    xiaoxiao2025-04-23  6

    下面是我写的一个下载两种不同类型文件的程序案例: Download.java: package com.mycompany.download; import android.os.StrictMode; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; import java.net.HttpURLConnection; public class Download extends AppCompatActivity { private Button txtButton; private Button mp3Button; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_download); txtButton = (Button)findViewById(R.id.txtButton); mp3Button = (Button)findViewById(R.id.mp3Button); txtButton.setOnClickListener(new txtButtonListener()); mp3Button.setOnClickListener(new mp3ButtonListener()); } class txtButtonListener implements View.OnClickListener{ @Override public void onClick(View v) { Thread t = new MyThread1(); t.start(); } } class mp3ButtonListener implements View.OnClickListener{ @Override public void onClick(View v) { Thread t = new MyThread2(); t.start(); } } class MyThread1 extends Thread{ @Override public void run() { HttpDownloader httpDownloader = new HttpDownloader(); String lrc = httpDownloader.download("http://qukufile2.qianqian.com/data2/lrc/2bd596497968b5286228bb8339326d82/261127925/261127925.lrc"); System.out.println(lrc); } } class MyThread2 extends Thread{ @Override public void run() { HttpDownloader httpDownloader = new HttpDownloader(); int result = httpDownloader.downFile("http://image.baidu.com/search/down?tn=download&word=download&ie=utf8&fr=detail&url=http%3A%2F%2Fpic48.nipic.com%2Ffile%2F20140910%2F6365066_112611596403_2.jpg&thumburl=http%3A%2F%2Fimg0.imgtn.bdimg.com%2Fit%2Fu%3D2486202150%2C517659072%26fm%3D21%26gp%3D0.jpg","beauties/","2.jpg"); // 目录加上"/"方便文件的创建 System.out.println(result); } } } 需要注意的是,如果直接将网络下载的相关代码放进OnCreate()方法中,Android Studio会提示主线程负担过重,并且将会导致下载失败,出现NetworkOnMainThreadException异常,原因是从Honeycomb SDK(3.0)开始,google不再允许网络请求(HTTP、Socket)等相关操作直接在Main Thread类中。直接在UI线程进行网络操作,会阻塞UI、降低用户体验。所以,在Honeycomb SDK(3.0)以下的版本,你还可以继续在Main Thread里这样做,在3.0以上,就不行了,建议将和network有关比较耗时的操作放到一个子线程里。 1.使用HTTP协议下载文件 文件下载步骤 1)创建一个HttpURLConnection对象 HttpURLConnection urlConn = (HttpURLConnection)url.openConnection(); 2)获得一个InputStream对象 urlConn.getInputStream() 3)访问网络的权限 android.permission.INTERNET 2.将下载的文件写入SDCARD 下载文本文件:(download()方法) 首先创建一个URL对象,将文件下载地址传给该对象,然后利用url对象的openConnection()方法打开连接,并赋给一个HttpURLConnection对象。接着调用HttpURLConnection对象的getInputStream方法得到InputStream,然后利用IO流(BufferedReader对象和readLine()方法)读取文件的数据至一个StringBuffer对象,最后将该对象转换成String类型并返回。 public String download(String urlStr){ StringBuffer stringBuffer = new StringBuffer(); String line; BufferedReader bufferedReader = null; try{ // 创建一个URL对象 url = new URL(urlStr); // 创建一个Http连接 HttpURLConnection httpURLConnection = (HttpURLConnection)url.openConnection(); // 使用IO流读取数据 bufferedReader = new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream())); while ((line = bufferedReader.readLine()) != null){ stringBuffer.append(line); } }catch (Exception e){ e.printStackTrace(); }finally { try{ bufferedReader.close();; } catch (Exception e){ e.printStackTrace(); } } return stringBuffer.toString(); } 注:用该方法下载的TXT文件并没有保存到内存卡中,要想保存请使用下面的方法。 下载任何类型的文件:(downFile()方法) public int downFile(String urlStr, String path, String fileName){ InputStream inputStream = null; try { FileUtils fileUtils = new FileUtils(); if(fileUtils.isFileExist(path + fileName)){ return 1; } else{ inputStream = getInputStreamFromUrl(urlStr); File resultFile = fileUtils.write2SDFromInput(path,fileName,inputStream); if(resultFile == null){ return -1; } } }catch (Exception e){ e.printStackTrace(); return -1; }finally { try { inputStream.close(); }catch (Exception e){ e.printStackTrace(); } } return 0; } // 根据URL得到输入流 // 该方法是创建URL对象、打开连接、得到InputStream过程的封装 public InputStream getInputStreamFromUrl(String urlStr) throws MalformedURLException,IOException{ url = new URL(urlStr); HttpURLConnection urlConn = (HttpURLConnection)url.openConnection(); InputStream inputStream = urlConn.getInputStream(); return inputStream; } } 以下是工具类: FileUtils.java: package com.mycompany.download; import android.os.Environment; import android.provider.ContactsContract; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; /** * Created by Administrator on 2016/8/14. */ public class FileUtils { private String SDPATH; public String getSDPATH(){ return SDPATH; } public FileUtils (){ // 得到SD卡的目录 SDPATH = Environment.getExternalStorageDirectory() + "/"; } // 在SD卡上创建文件 public File creatSDFile(String fileName) throws IOException{ File file = new File(SDPATH + fileName); file.createNewFile(); return file; } // 在SD卡上创建目录 public File creatSDDir(String dirName){ File dir = new File(SDPATH + dirName); dir.mkdir(); return dir; } // 判断SD卡上的文件夹是否存在 public boolean isFileExist(String fileName){ File file = new File(SDPATH + fileName); return file.exists(); } // 将一个InputStream里面的数据写入到SD卡中 public File write2SDFromInput(String path,String fileName,InputStream input){ File file = null; OutputStream output = null; try{ creatSDDir(path); file = creatSDFile(path + fileName); // 利用字节流将InputStream中的数据写入到新建的文件中 output = new FileOutputStream(file); byte[] buffer = new byte[4 * 1024]; int len; while ((len=input.read(buffer))!= -1) { output.write(buffer,0,len); } output.flush(); // 清空缓存 }catch (Exception e){ e.printStackTrace(); }finally { try{ output.close(); }catch (Exception e){ e.printStackTrace(); } } return file; } } HttpDownloader.java: package com.mycompany.download; 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; /** * Created by Administrator on 2016/8/14. */ public class HttpDownloader { private URL url = null; public String download(String urlStr){ StringBuffer stringBuffer = new StringBuffer(); String line; BufferedReader bufferedReader = null; try{ // 创建一个URL对象 url = new URL(urlStr); // 创建一个Http连接 HttpURLConnection httpURLConnection = (HttpURLConnection)url.openConnection(); // 使用IO流读取数据 bufferedReader = new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream())); while ((line = bufferedReader.readLine()) != null){ stringBuffer.append(line); } }catch (Exception e){ e.printStackTrace(); }finally { try{ bufferedReader.close();; } catch (Exception e){ e.printStackTrace(); } } return stringBuffer.toString(); } // 该函数返回 -1:代表下载文件出错,0代表下载文件成功,1代表文件已经存在 public int downFile(String urlStr, String path, String fileName){ InputStream inputStream = null; try { FileUtils fileUtils = new FileUtils(); if(fileUtils.isFileExist(path + fileName)){ return 1; } else{ inputStream = getInputStreamFromUrl(urlStr); File resultFile = fileUtils.write2SDFromInput(path,fileName,inputStream); if(resultFile == null){ return -1; } } }catch (Exception e){ e.printStackTrace(); return -1; }finally { try { inputStream.close(); }catch (Exception e){ e.printStackTrace(); } } return 0; } // 根据URL得到输入流 // 该方法是创建URL对象、打开连接、得到InputStream过程的封装 public InputStream getInputStreamFromUrl(String urlStr) throws MalformedURLException,IOException{ url = new URL(urlStr); HttpURLConnection urlConn = (HttpURLConnection)url.openConnection(); InputStream inputStream = urlConn.getInputStream(); return inputStream; } } 最后不要忘记在AndroidManifest.java中添加两个权限: <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> 经测试,在API 19的机器上软件运行正常,在API 23上则运行失败。原因不详。

    需要注意的是,如果直接将网络下载的相关代码放进OnCreate()方法中,Android Studio会提示主线程负担过重,并且将会导致下载失败,出现NetworkOnMainThreadException异常,原因是从Honeycomb SDK(3.0)开始,google不再允许网络请求(HTTP、Socket)等相关操作直接在Main Thread类中。直接在UI线程进行网络操作,会阻塞UI、降低用户体验。所以,在Honeycomb SDK(3.0)以下的版本,你还可以继续在Main Thread里这样做,在3.0以上,就不行了,建议将和network有关比较耗时的操作放到一个子线程里。
    转载请注明原文地址: https://ju.6miu.com/read-1298377.html
    最新回复(0)