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

     

[xhtml:firstline[1]] view plaincopy
 
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:orientation="vertical"  
  4.     android:layout_width="fill_parent"  
  5.     android:layout_height="fill_parent"  
  6.     >  
  7. <TextView    
  8.     android:layout_width="fill_parent"   
  9.     android:layout_height="wrap_content"   
  10.     android:text="@string/hello"  
  11.     />  
  12. <Button  
  13.     android:id="@+id/buttontxt"  
  14.     android:layout_width="300dp"  
  15.     android:layout_height="wrap_content"  
  16.     android:text="单击下载txt文件"  
  17.     />  
  18. <Button  
  19.     android:id="@+id/buttonmp3"  
  20.     android:layout_width="300dp"  
  21.     android:layout_height="wrap_content"  
  22.     android:text="单击下载mp3文件"  
  23.     />  
  24. </LinearLayout>  
 

Android_Download.java

    

[java:firstline[1]] view plaincopy
 
  1. package idea.org;  
  2.   
  3. import android.app.Activity;  
  4. import android.os.Bundle;  
  5. import android.view.View;  
  6. import android.view.View.OnClickListener;  
  7. import android.widget.Button;  
  8.   
  9. public class Android_Download extends Activity {  
  10.     private Button buttontxt;  
  11.     private Button buttonmp3;  
  12.     /** Called when the activity is first created. */  
  13.     @Override  
  14.     public void onCreate(Bundle savedInstanceState) {  
  15.         super.onCreate(savedInstanceState);  
  16.         setContentView(R.layout.main);  
  17.         buttontxt=(Button)findViewById(R.id.buttontxt);  
  18.         //为buttontxt添加单击事件监听器  
  19.         buttontxt.setOnClickListener(new OnClickListener(){  
  20.   
  21.             /* (non-Javadoc) 
  22.              * @see android.view.View.OnClickListener#onClick(android.view.View) 
  23.              */  
  24.             @Override  
  25.             public void onClick(View v) {  
  26.                 // TODO Auto-generated method stub  
  27.                 //创建一个匿名线程用于下载文件  
  28.                 new Thread()  
  29.                 {  
  30.                     public void run()  
  31.                     {  
  32.                         HttpDownloader httpDownloader=new HttpDownloader();   
  33.                         //调用httpDownloader对象的重载方法download下载txt文件  
  34.                         String txt=httpDownloader.download("http://172.24.24.20:8080/Android/a.txt");                 
  35.                         System.out.println(txt);  
  36.                     }  
  37.                 }.start();  
  38.             }  
  39.               
  40.         });  
  41.         buttonmp3=(Button)findViewById(R.id.buttonmp3);  
  42.         //为buttonmp3添加单击事件监听器  
  43.         buttonmp3.setOnClickListener(new OnClickListener()  
  44.         {  
  45.   
  46.             /* (non-Javadoc) 
  47.              * @see android.view.View.OnClickListener#onClick(android.view.View) 
  48.              */  
  49.             @Override  
  50.             public void onClick(View v) {  
  51.                 // TODO Auto-generated method stub  
  52.                 new Thread()  
  53.                 {  
  54.                     public void run()  
  55.                     {  
  56.                         try  
  57.                         {  
  58.                             HttpDownloader httpDownloader=new HttpDownloader();  
  59.                             //调用httpDownloader对象的重载方法download下载mp3文件  
  60.                             int result=httpDownloader.download("http://172.24.24.20:8080/Android/music.mp3","Android/","music.mp3");  
  61.                             System.out.println(result);  
  62.                             }  
  63.                             catch(Exception e)  
  64.                             {  
  65.                                 e.printStackTrace();  
  66.                             }     
  67.                         }  
  68.                 }.start();  
  69.                   
  70.             }  
  71.         });  
  72.     }  
  73. }  

HttpDownloader.java

    

[java:firstline[1]] view plaincopy
 
  1. package idea.org;  
  2. import java.io.BufferedReader;  
  3. import java.io.File;  
  4. import java.io.IOException;  
  5. import java.io.InputStream;  
  6. import java.io.InputStreamReader;  
  7. import java.net.HttpURLConnection;  
  8. import java.net.URL;  
  9. public class HttpDownloader {  
  10.     private URL url=null;  
  11.     public String download(String urlStr)  
  12.     {  
  13.         StringBuffer stringbuffer=new StringBuffer();  
  14.         String line;  
  15.         BufferedReader bufferReader=null;  
  16.         try  
  17.         {  
  18.             //创建一个URL对象  
  19.             url=new URL(urlStr);              
  20.             //得到一个HttpURLConnection对象  
  21.             HttpURLConnection httpUrlConnection=(HttpURLConnection) url.openConnection();     
  22.             // 得到IO流,使用IO流读取数据  
  23.             bufferReader=new BufferedReader(new InputStreamReader(httpUrlConnection.getInputStream()));  
  24.             while((line=bufferReader.readLine())!=null)  
  25.             {                 
  26.                 stringbuffer.append(line);  
  27.             }             
  28.         }  
  29.         catch(Exception e)  
  30.         {  
  31.             e.printStackTrace();  
  32.         }                 
  33.         return stringbuffer.toString();  
  34.           
  35.     }  
  36.     // 该函数返回整形 -1:代表下载文件出错 ;0:代表下载文件成功; 1:代表文件已经存在  
  37.     public int download(String urlStr,String path,String fileName)  
  38.     {  
  39.         InputStream inputstream=null;  
  40.         FileUtils fileUtils=new FileUtils();  
  41.         if(fileUtils.isExist(path+fileName))  
  42.             return 1;  
  43.         else  
  44.         {  
  45.             try {  
  46.                 inputstream=getFromUrl(urlStr);  
  47.             } catch (IOException e) {  
  48.                 // TODO Auto-generated catch block  
  49.                 e.printStackTrace();  
  50.             }  
  51.             File file=fileUtils.writeToSDPATHFromInput(path, fileName, inputstream);  
  52.             if(file!=null)  
  53.                 return 0;  
  54.             else   
  55.                 return -1;  
  56.         }  
  57.     }  
  58.     //根据url字符串得到输入流  
  59.     public InputStream getFromUrl(String urlStr) throws IOException  
  60.     {         
  61.         url=new URL(urlStr);              
  62.         HttpURLConnection httpUrlConnection=(HttpURLConnection) url.openConnection();  
  63.         InputStream input=httpUrlConnection.getInputStream();     
  64.         return input;  
  65.     }  
  66. }  

FileUtils.java

    

[java:firstline[1]] view plaincopy
 
  1. package idea.org;  
  2. import java.io.File;  
  3. import java.io.FileOutputStream;  
  4. import java.io.IOException;  
  5. import java.io.InputStream;  
  6. import java.io.OutputStream;  
  7. import android.os.Environment;  
  8.   
  9.   
  10. public class FileUtils {  
  11.     private String SDPATH=null;  
  12.     public String getSDPATH()  
  13.     {  
  14.         return SDPATH;  
  15.     }  
  16.     public FileUtils()  
  17.     {  
  18.         //获得当前外部存储设备SD卡的目录  
  19.         SDPATH=Environment.getExternalStorageDirectory()+"/";  
  20.     }  
  21.     //创建文件  
  22.     public File createFile(String fileName) throws IOException  
  23.     {  
  24.         File file=new File(SDPATH+fileName);  
  25.         file.createNewFile();  
  26.         return file;  
  27.     }  
  28.     //创建目录  
  29.     public File createDir(String fileName) throws IOException  
  30.     {  
  31.         File dir=new File(SDPATH+fileName);       
  32.         dir.mkdir();  
  33.         return dir;  
  34.     }  
  35.     //判断文件是否存在  
  36.     public boolean isExist(String fileName)  
  37.     {  
  38.         File file=new File(SDPATH+fileName);  
  39.         return file.exists();  
  40.     }  
  41.     public File writeToSDPATHFromInput(String path,String fileName,InputStream inputstream)  
  42.     {  
  43.         File file=null;  
  44.         OutputStream outputstream=null;  
  45.         try  
  46.         {  
  47.             createDir(path);  
  48.             file=createFile(path+fileName);  
  49.             outputstream=new FileOutputStream(file);  
  50.             byte buffer[]=new byte[1024];  
  51.             //将输入流中的内容先输入到buffer中缓存,然后用输出流写到文件中  
  52.             while((inputstream.read(buffer))!=-1)  
  53.             {  
  54.                 outputstream.write(buffer);  
  55.             }  
  56.         }  
  57.         catch(Exception e)  
  58.         {  
  59.             e.printStackTrace();  
  60.         }  
  61.         finally  
  62.         {  
  63.             try {  
  64.                 outputstream.close();  
  65.             } catch (IOException e) {  
  66.                 // TODO Auto-generated catch block  
  67.                 e.printStackTrace();  
  68.             }  
  69.         }  
  70.         return file;  
  71.     }  
  72. }  

Android_Download Manifest.xml

    

[xhtml:firstline[1]] view plaincopy
 
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"  
  3.       package="idea.org"  
  4.       android:versionCode="1"  
  5.       android:versionName="1.0">  
  6.     <uses-sdk android:minSdkVersion="11" />  
  7.   
  8.     <application android:icon="@drawable/icon" android:label="@string/app_name">  
  9.         <activity android:name=".Android_Download"  
  10.                   android:label="@string/app_name">  
  11.             <intent-filter>  
  12.                 <action android:name="android.intent.action.MAIN" />  
  13.                 <category android:name="android.intent.category.LAUNCHER" />  
  14.             </intent-filter>  
  15.         </activity>  
  16.   
  17.     </application>     
  18.     <uses-permission android:name="android.permission.INTERNET"/>      
  19.     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>  
  20. </manifest>  

运行结果:

     界面

     

     依次点击两个Button按钮之后控制台输出的信息。

     

     a.txt文件中有中文,由于log日志只能输出英文字符,所以会出现乱码。现在mp3时输出download()方法的返回值0,说明下载成功。

     如果这个时候我们再点击点击一次buttonmp3按钮,会输出返回值1,说明文件已经存在。

     

     我们可以通过DDMS视图中的工具File Explorer查看虚拟机中SD卡目录中我们下载的文件。

     

路漫漫其修远兮 吾将上下而求索
原文地址:https://www.cnblogs.com/hudabing/p/3109882.html