下面是我写的一个下载两种不同类型文件的程序案例:
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