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. 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. new HttpDownloader();   
33. //调用httpDownloader对象的重载方法download下载txt文件  
34. "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. 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. 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.     }
  1. }  

 

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. new StringBuffer();  
14.         String line;  
15. null;  
16. try  
17.         {  
18. //创建一个URL对象  
19. new URL(urlStr);              
20. //得到一个HttpURLConnection对象  
21.             HttpURLConnection httpUrlConnection=(HttpURLConnection) url.openConnection();     
22. // 得到IO流,使用IO流读取数据  
23. 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. null;  
40. 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. 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. "/";  
20.     }  
21. //创建文件  
22. public File createFile(String fileName) throws IOException  
23.     {  
24. new File(SDPATH+fileName);  
25.         file.createNewFile();  
26. return file;  
27.     }  
28. //创建目录  
29. public File createDir(String fileName) throws IOException  
30.     {  
31. new File(SDPATH+fileName);       
32.         dir.mkdir();  
33. return dir;  
34.     }  
35. //判断文件是否存在  
36. public boolean isExist(String fileName)  
37.     {  
38. new File(SDPATH+fileName);  
39. return file.exists();  
40.     }  
41. public File writeToSDPATHFromInput(String path,String fileName,InputStream inputstream)  
42.     {  
43. null;  
44. null;  
45. try  
46.         {  
47.             createDir(path);  
48.             file=createFile(path+fileName);  
49. 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卡目录中我们下载的文件。

     

分享到: 

  • buffer 需要 修正!

路漫漫其修远兮 吾将上下而求索