Android开发之文件下载
Android作为一个手机操作系统,在Android中访问网络是许多应用程序都必需的功能。用户也经常需要在应用程序中下载所需要的文件比如电子书,MP3格式的音乐文件,电影等。
Android文件下载的一般步骤:
1、创建一个HttpURLConnection的对象
URL url=new URL(urlStr);
HtttpURLConnection urlConn=(HtttpURLConnection)url.OpenConnection();
2、获取一个InputStream输入流对象
urlConn.getInputStream();
3、在AndroidManifest.xml中添加网络访问权限
<uses-permission android:name="android.permission.INTERNET"/>
4、在AndroidManifest.xml中加入访问SDCard的权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
5、创建文件流FileOutputStream,将从InputStream读出的数据写入到FileOutputStream。
需要注意的是在Android3.0之前的Android平台上可以直接Activity所在的线程中访问网络,下载网络上的文件。但是这样的话,如果下载的文件较大,或者网速比较慢的情况下,Activity界面就会处于无法及时响应用户操作的状态。Android3.0中如果在Activity所在的线程访问网络,调试执行时会出现异常信息:“android.os.NetworkOnMainThreadException”,无法获取有效的HttpURLConnection对象。所以我们需要把访问网络,下载文件的操作放在另外的线程中。
示例:
新建一个Android应用程序项目。在main.xml总添加两个Button:buttontxt、buttonmp3。点击分别下载txt和mp3文件。下载的txt文件直接将txt文本文件的内容直接输出到控制台。mp3文件保存到虚拟结的SD卡目录下的Android文件夹中。为了下载方便,项目中下载的a.txt和music.mp3文件均放在本机安装的tomcat服务器上webapps目录下的Android文件夹中。
main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello" /> <Button android:id="@+id/buttontxt" android:layout_width="300dp" android:layout_height="wrap_content" android:text="单击下载txt文件" /> <Button android:id="@+id/buttonmp3" android:layout_width="300dp" android:layout_height="wrap_content" android:text="单击下载mp3文件" /> </LinearLayout>
Android_Download.java
package idea.org; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; public class Android_Download extends Activity { private Button buttontxt; private Button buttonmp3; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); buttontxt=(Button)findViewById(R.id.buttontxt); //为buttontxt添加单击事件监听器 buttontxt.setOnClickListener(new OnClickListener(){ /* (non-Javadoc) * @see android.view.View.OnClickListener#onClick(android.view.View) */ @Override public void onClick(View v) { // TODO Auto-generated method stub //创建一个匿名线程用于下载文件 new Thread() { public void run() { HttpDownloader httpDownloader=new HttpDownloader(); //调用httpDownloader对象的重载方法download下载txt文件 String txt=httpDownloader.download("http://172.24.24.20:8080/Android/a.txt"); System.out.println(txt); } }.start(); } }); buttonmp3=(Button)findViewById(R.id.buttonmp3); //为buttonmp3添加单击事件监听器 buttonmp3.setOnClickListener(new OnClickListener() { /* (non-Javadoc) * @see android.view.View.OnClickListener#onClick(android.view.View) */ @Override public void onClick(View v) { // TODO Auto-generated method stub new Thread() { public void run() { try { HttpDownloader httpDownloader=new HttpDownloader(); //调用httpDownloader对象的重载方法download下载mp3文件 int result=httpDownloader.download("http://172.24.24.20:8080/Android/music.mp3","Android/","music.mp3"); System.out.println(result); } catch(Exception e) { e.printStackTrace(); } } }.start(); } }); } }
HttpDownloader.java
package idea.org; 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.URL; public class HttpDownloader { private URL url=null; public String download(String urlStr) { StringBuffer stringbuffer=new StringBuffer(); String line; BufferedReader bufferReader=null; try { //创建一个URL对象 url=new URL(urlStr); //得到一个HttpURLConnection对象 HttpURLConnection httpUrlConnection=(HttpURLConnection) url.openConnection(); // 得到IO流,使用IO流读取数据 bufferReader=new BufferedReader(new InputStreamReader(httpUrlConnection.getInputStream())); while((line=bufferReader.readLine())!=null) { stringbuffer.append(line); } } catch(Exception e) { e.printStackTrace(); } return stringbuffer.toString(); } // 该函数返回整形 -1:代表下载文件出错 ;0:代表下载文件成功; 1:代表文件已经存在 public int download(String urlStr,String path,String fileName) { InputStream inputstream=null; FileUtils fileUtils=new FileUtils(); if(fileUtils.isExist(path+fileName)) return 1; else { try { inputstream=getFromUrl(urlStr); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } File file=fileUtils.writeToSDPATHFromInput(path, fileName, inputstream); if(file!=null) return 0; else return -1; } } //根据url字符串得到输入流 public InputStream getFromUrl(String urlStr) throws IOException { url=new URL(urlStr); HttpURLConnection httpUrlConnection=(HttpURLConnection) url.openConnection(); InputStream input=httpUrlConnection.getInputStream(); return input; } }
FileUtils.java
package idea.org; 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 FileUtils { private String SDPATH=null; public String getSDPATH() { return SDPATH; } public FileUtils() { //获得当前外部存储设备SD卡的目录 SDPATH=Environment.getExternalStorageDirectory()+"/"; } //创建文件 public File createFile(String fileName) throws IOException { File file=new File(SDPATH+fileName); file.createNewFile(); return file; } //创建目录 public File createDir(String fileName) throws IOException { File dir=new File(SDPATH+fileName); dir.mkdir(); return dir; } //判断文件是否存在 public boolean isExist(String fileName) { File file=new File(SDPATH+fileName); return file.exists(); } public File writeToSDPATHFromInput(String path,String fileName,InputStream inputstream) { File file=null; OutputStream outputstream=null; try { createDir(path); file=createFile(path+fileName); outputstream=new FileOutputStream(file); byte buffer[]=new byte[1024]; //将输入流中的内容先输入到buffer中缓存,然后用输出流写到文件中 while((inputstream.read(buffer))!=-1) { outputstream.write(buffer); } } catch(Exception e) { e.printStackTrace(); } finally { try { outputstream.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } return file; } }
Android_Download Manifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="idea.org" android:versionCode="1" android:versionName="1.0"> <uses-sdk android:minSdkVersion="11" /> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".Android_Download" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> </manifest>
运行结果:
界面
依次点击两个Button按钮之后控制台输出的信息。
a.txt文件中有中文,由于log日志只能输出英文字符,所以会出现乱码。现在mp3时输出download()方法的返回值0,说明下载成功。
如果这个时候我们再点击点击一次buttonmp3按钮,会输出返回值1,说明文件已经存在。
我们可以通过DDMS视图中的工具File Explorer查看虚拟机中SD卡目录中我们下载的文件。
更多相关文章
- 类和 Json对象
- NPM 和webpack 的基础使用
- 【阿里云镜像】使用阿里巴巴DNS镜像源——DNS配置教程
- Android(安卓)获取手机流量
- android 设置listview item选中背景色
- 2-8 Android(安卓)简单介绍 (一)
- SE for Android(安卓)系列之整体概要(三)
- ubuntu搭建Android(安卓)NDK环境与Android(安卓)Studio简单使用N
- AndroidManifest.xml文件剖析 (二)