Java和Android Http连接程序:使用java.net.URL 下载服务器图片到客户端

  本博客前面博文中利用org.apache.http包中API进行Android客户端HTTP连接的例子:

  Android HTTP实例 发送请求和接收响应

  Android HTTP实例 使用GET方法和POST方法发送请求

  

  另一种常用的建立Http连接的常用方式是利用Java在JDK中提供的类,也即本文要演示的方法,本文的例子程序实现的功能是从服务器上下载图片到客户端

  关于两种建立Http连接方法(apache的包和JDK的包)的讨论可以看看后面的参考链接。

服务器端

  服务器端需要准备图片,因为是Demo程序,所以我就准备了一张图片,然后把它放在Web Project的WebRoot路径下:

  然后只要启动Tomcat,ipconfig查出ip地址,放在之后要用的路径中就可以了。

Java程序:Http连接 获取并下载服务器端图片

  写一个工具类:

  其中第一个方法根据给出的服务器地址及资源路径得到输入流

  1. public static InputStream getInputStream(String path)
  2. {
  3. InputStream inputStream = null;
  4. HttpURLConnection httpURLConnection = null;
  5.  
  6. try
  7. {
  8. URL url = new URL(path);
  9. if (null != url)
  10. {
  11. httpURLConnection = (HttpURLConnection) url.openConnection();
  12.  
  13. // 设置连接网络的超时时间
  14. httpURLConnection.setConnectTimeout(5000);
  15.  
  16. // 打开输入流
  17. httpURLConnection.setDoInput(true);
  18.  
  19. // 设置本次Http请求使用的方法
  20. httpURLConnection.setRequestMethod("GET");
  21.  
  22. if (200 == httpURLConnection.getResponseCode())
  23. {
  24. // 从服务器获得一个输入流
  25. inputStream = httpURLConnection.getInputStream();
  26.  
  27. }
  28.  
  29. }
  30. }
  31. catch (MalformedURLException e)
  32. {
  33. e.printStackTrace();
  34. }
  35. catch (IOException e)
  36. {
  37. e.printStackTrace();
  38. }
  39. return inputStream;
  40. }

  第二个方法根据输入流将文件存储在本地一个路径

  1. public static void saveInputStream(InputStream inputStream,
  2. String saveToPath)
  3. {
  4.  
  5. byte[] data = new byte[1024];
  6. int len = 0;
  7.  
  8. FileOutputStream fileOutputStream = null;
  9. try
  10. {
  11.  
  12. fileOutputStream = new FileOutputStream(saveToPath);
  13. while (-1 != (len = inputStream.read(data)))
  14. {
  15.  
  16. fileOutputStream.write(data, 0, len);
  17.  
  18. }
  19. }
  20. catch (IOException e)
  21. {
  22. e.printStackTrace();
  23. }
  24. finally
  25. {
  26. if (null != inputStream)
  27. {
  28. try
  29. {
  30. inputStream.close();
  31. }
  32. catch (IOException e)
  33. {
  34. e.printStackTrace();
  35. }
  36. }
  37.  
  38. if (null != fileOutputStream)
  39. {
  40.  
  41. try
  42. {
  43. fileOutputStream.close();
  44. }
  45. catch (IOException e)
  46. {
  47. e.printStackTrace();
  48. }
  49. }
  50. }
  51. }

  完整代码:

  1. package com.meng.utils;
  2.  
  3. import java.io.FileOutputStream;
  4. import java.io.IOException;
  5. import java.io.InputStream;
  6. import java.net.HttpURLConnection;
  7. import java.net.MalformedURLException;
  8. import java.net.URL;
  9.  
  10. public class HttpUtils
  11. {
  12.  
  13. public static InputStream getInputStream(String path)
  14. {
  15. InputStream inputStream = null;
  16. HttpURLConnection httpURLConnection = null;
  17.  
  18. try
  19. {
  20. URL url = new URL(path);
  21. if (null != url)
  22. {
  23. httpURLConnection = (HttpURLConnection) url.openConnection();
  24.  
  25. // 设置连接网络的超时时间
  26. httpURLConnection.setConnectTimeout(5000);
  27.  
  28. // 打开输入流
  29. httpURLConnection.setDoInput(true);
  30.  
  31. // 设置本次Http请求使用的方法
  32. httpURLConnection.setRequestMethod("GET");
  33.  
  34. if (200 == httpURLConnection.getResponseCode())
  35. {
  36. // 从服务器获得一个输入流
  37. inputStream = httpURLConnection.getInputStream();
  38.  
  39. }
  40.  
  41. }
  42. }
  43. catch (MalformedURLException e)
  44. {
  45. e.printStackTrace();
  46. }
  47. catch (IOException e)
  48. {
  49. e.printStackTrace();
  50. }
  51. return inputStream;
  52. }
  53.  
  54. public static void saveInputStream(InputStream inputStream,
  55. String saveToPath)
  56. {
  57.  
  58. byte[] data = new byte[1024];
  59. int len = 0;
  60.  
  61. FileOutputStream fileOutputStream = null;
  62. try
  63. {
  64.  
  65. fileOutputStream = new FileOutputStream(saveToPath);
  66. while (-1 != (len = inputStream.read(data)))
  67. {
  68.  
  69. fileOutputStream.write(data, 0, len);
  70.  
  71. }
  72. }
  73. catch (IOException e)
  74. {
  75. e.printStackTrace();
  76. }
  77. finally
  78. {
  79. if (null != inputStream)
  80. {
  81. try
  82. {
  83. inputStream.close();
  84. }
  85. catch (IOException e)
  86. {
  87. e.printStackTrace();
  88. }
  89. }
  90.  
  91. if (null != fileOutputStream)
  92. {
  93.  
  94. try
  95. {
  96. fileOutputStream.close();
  97. }
  98. catch (IOException e)
  99. {
  100. e.printStackTrace();
  101. }
  102. }
  103. }
  104. }
  105.  
  106. }

HttpUtils.java

  测试程序:

  1. package com.meng.learn;
  2.  
  3. import java.io.InputStream;
  4. import com.meng.utils.HttpUtils;
  5.  
  6. public class HttpTest
  7. {
  8. private static String URL_PATH = "http://192.168.11.6:8080/HelloWeb/android.jpg";
  9.  
  10. public static void main(String[] args)
  11. {
  12. InputStream inputStream = HttpUtils.getInputStream(URL_PATH);
  13. HttpUtils.saveInputStream(inputStream,"D:\\test1.jpg");
  14.  
  15. }
  16.  
  17. }

  程序运行成功之后可以在指定路径下发现多了服务器端的那个图片。

Android客户端 Http连接:下载服务器端的图片到SD卡

  Android的程序还需要考虑的几点是:

  1.对SD卡的访问权限及操作。

  2.为了不阻塞UI线程,下载操作放在独立的线程中。

  3.加入了网路访问的检查,确认网络连接后再进行下载。

需要添加的权限

  1. <!-- 往SDCard写入数据权限 -->
  2. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  3. <!-- 联网权限 -->
  4. <uses-permission android:name="android.permission.INTERNET" />
  5. <!-- 获取网络状态的权限 -->
  6. <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

  布局文件如下:

  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. xmlns:tools="http://schemas.android.com/tools"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. android:orientation="vertical" >
  6.  
  7. <TextView
  8. android:padding="10dp"
  9. android:id="@+id/info"
  10. android:layout_width="match_parent"
  11. android:layout_height="wrap_content"
  12. android:textSize="14sp" />
  13.  
  14. <Button
  15. android:id="@+id/btn"
  16. android:layout_width="match_parent"
  17. android:layout_height="wrap_content"
  18. android:text="Download Image"
  19. android:textSize="14sp" />
  20.  
  21. <ImageView
  22. android:padding="10dp"
  23. android:id="@+id/image"
  24. android:layout_width="match_parent"
  25. android:layout_height="match_parent" />
  26.  
  27. </LinearLayout>

activity_image_download.xml

  Activity中所做的就是按下按钮之后,连接服务器,将图片取出显示在ImageView里,同时存往SD卡的指定路径:

  1. package com.mengexample.test;
  2.  
  3. import java.io.InputStream;
  4.  
  5. import com.windexample.utils.FileUtils;
  6. import com.windexample.utils.HttpUtils;
  7.  
  8. import android.app.Activity;
  9. import android.content.Context;
  10. import android.graphics.Bitmap;
  11. import android.graphics.BitmapFactory;
  12. import android.net.ConnectivityManager;
  13. import android.net.NetworkInfo;
  14. import android.os.AsyncTask;
  15. import android.os.Bundle;
  16. import android.view.View;
  17. import android.view.View.OnClickListener;
  18. import android.widget.Button;
  19. import android.widget.ImageView;
  20. import android.widget.TextView;
  21. import android.widget.Toast;
  22.  
  23. public class ImageDownloadActivity extends Activity
  24. {
  25. private static String URL_PATH = "http://192.168.11.6:8080/HelloWeb/android.jpg";
  26.  
  27. private TextView mTextView = null;
  28. private Button mButton = null;
  29. private ImageView mImageView = null;
  30.  
  31. @Override
  32. protected void onCreate(Bundle savedInstanceState)
  33. {
  34. super.onCreate(savedInstanceState);
  35. setContentView(R.layout.activity_image_download);
  36.  
  37. mTextView = (TextView) findViewById(R.id.info);
  38. mTextView.setText(URL_PATH);
  39. mButton = (Button) findViewById(R.id.btn);
  40. mButton.setOnClickListener(mBtnClickListener);
  41. mImageView = (ImageView) findViewById(R.id.image);
  42.  
  43. }
  44.  
  45. private OnClickListener mBtnClickListener = new OnClickListener()
  46. {
  47.  
  48. @Override
  49. public void onClick(View v)
  50. {
  51. // 首先确认网络连接
  52. ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
  53. NetworkInfo networkInfo = connectivityManager
  54. .getActiveNetworkInfo();
  55. if (null != networkInfo && networkInfo.isConnected())
  56. {
  57. new DownloadImageTask().execute(URL_PATH);
  58. }
  59. else
  60. {
  61. Toast.makeText(ImageDownloadActivity.this,
  62. "No network connection available", Toast.LENGTH_SHORT)
  63. .show();
  64. }
  65. }
  66. };
  67.  
  68. private class DownloadImageTask extends AsyncTask<String, Void, Bitmap>
  69. {
  70.  
  71. @Override
  72. protected Bitmap doInBackground(String... params)
  73. {
  74. String path = params[0];
  75.  
  76. InputStream inputStream = HttpUtils.getInputStream(path);
  77.  
  78. // 从输入流得到位图
  79. Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
  80.  
  81. // 将图像存储到SD卡
  82. FileUtils.saveToSDCard(bitmap, "TestImage", "android.jpg");
  83.  
  84. return bitmap;
  85. }
  86.  
  87. @Override
  88. protected void onPostExecute(Bitmap result)
  89. {
  90. // 将图像显示出来
  91. mImageView.setImageBitmap(result);
  92. }
  93.  
  94. }
  95.  
  96. }

  

  其中用到的两个工具类:

  建立连接并获取输入流的方法和Java代码中的一样:

  1. package com.windexample.utils;
  2.  
  3. import java.io.IOException;
  4. import java.io.InputStream;
  5. import java.net.HttpURLConnection;
  6. import java.net.MalformedURLException;
  7. import java.net.URL;
  8.  
  9. public class HttpUtils
  10. {
  11.  
  12. public static InputStream getInputStream(String path)
  13. {
  14. InputStream inputStream = null;
  15. HttpURLConnection httpURLConnection = null;
  16.  
  17. try
  18. {
  19. URL url = new URL(path);
  20. if (null != url)
  21. {
  22. httpURLConnection = (HttpURLConnection) url.openConnection();
  23.  
  24. // 设置连接网络的超时时间
  25. httpURLConnection.setConnectTimeout(5000);
  26.  
  27. // 打开输入流
  28. httpURLConnection.setDoInput(true);
  29.  
  30. // 设置本次Http请求使用的方法
  31. httpURLConnection.setRequestMethod("GET");
  32.  
  33. if (200 == httpURLConnection.getResponseCode())
  34. {
  35. // 从服务器获得一个输入流
  36. inputStream = httpURLConnection.getInputStream();
  37.  
  38. }
  39.  
  40. }
  41. }
  42. catch (MalformedURLException e)
  43. {
  44. e.printStackTrace();
  45. }
  46. catch (IOException e)
  47. {
  48. e.printStackTrace();
  49. }
  50. return inputStream;
  51. }
  52.  
  53. }

  

  另一个辅助类提供了方法,将位图存入SD卡的指定路径:

  1. package com.windexample.utils;
  2.  
  3. import java.io.File;
  4. import java.io.FileNotFoundException;
  5. import java.io.FileOutputStream;
  6. import java.io.IOException;
  7.  
  8. import android.graphics.Bitmap;
  9. import android.os.Environment;
  10. import android.util.Log;
  11.  
  12. public class FileUtils
  13. {
  14. private static String TAG = "File";
  15.  
  16. public static String getSDCardRootPath()
  17. {
  18. // SD卡根目录
  19. String sDCardRoot = Environment.getExternalStorageDirectory()
  20. .getAbsolutePath();
  21.  
  22. return sDCardRoot;
  23. }
  24.  
  25. public static void saveToSDCard(Bitmap bitmap, String filePath,
  26. String fileName)
  27. {
  28.  
  29. // 将所给文件路径和文件名与SD卡路径连接起来
  30. String sdcardRoot = getSDCardRootPath();
  31. // 创建文件路径
  32. File dir = new File(sdcardRoot + File.separator + filePath);
  33. Log.i(TAG, "dir: " + dir);
  34. if (!dir.exists())
  35. {
  36. dir.mkdirs();
  37. }
  38.  
  39. File targetFile = new File(dir, fileName);
  40.  
  41. try
  42. {
  43. targetFile.createNewFile();
  44. FileOutputStream fileOutputStream = new FileOutputStream(targetFile);
  45. bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fileOutputStream);
  46.  
  47. fileOutputStream.flush();
  48. fileOutputStream.close();
  49. }
  50. catch (FileNotFoundException e)
  51. {
  52. e.printStackTrace();
  53. }
  54. catch (IOException e)
  55. {
  56. e.printStackTrace();
  57. }
  58.  
  59. }
  60. }

  

  程序运行后并得到图片后,结果如下:

  并且查看SD卡下的TestImage路径,发现其中有这个图片文件。

参考资料

  Android Training: Connecting to the Network:

  http://developer.android.com/training/basics/network-ops/connecting.html

  Android Training: Processes and Threads

  http://developer.android.com/guide/components/processes-and-threads.html

  老罗Android开发视频教程。

  Android之网络编程 系列博文:

  http://www.cnblogs.com/devinzhang/category/349642.html

  本博客前面博文中利用org.apache.http包中API进行Android客户端HTTP连接的例子:

  Android HTTP实例 发送请求和接收响应

  Android HTTP实例 使用GET方法和POST方法发送请求

Java和Android Http连接程序:使用java.net.URL 下载服务器图片到客户端的更多相关文章

  1. Android Post方式发送信息和获取URL中的图片

    需要Internet权限,AndroidManifest.xml <uses-permission android:name="android.permission.INTERNET& ...

  2. Java面试不得不知的程序(二)

    [程序1]   题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少? 斐波那契数列:前面相邻两项之和,构 ...

  3. 052 01 Android 零基础入门 01 Java基础语法 05 Java流程控制之循环结构 14 Eclipse下程序调试——debug2 多断点调试程序

    052 01 Android 零基础入门 01 Java基础语法 05 Java流程控制之循环结构 14 Eclipse下程序调试--debug2 多断点调试程序 本文知识点: Eclipse下程序调 ...

  4. 051 01 Android 零基础入门 01 Java基础语法 05 Java流程控制之循环结构 13 Eclipse下程序调试——debug入门1

    051 01 Android 零基础入门 01 Java基础语法 05 Java流程控制之循环结构 13 Eclipse下程序调试--debug入门1 本文知识点: 程序调试--debug入门1 程序 ...

  5. 006 01 Android 零基础入门 01 Java基础语法 01 Java初识 06 使用Eclipse开发Java程序

    006 01 Android 零基础入门 01 Java基础语法 01 Java初识 06 使用Eclipse开发Java程序 Eclipse下创建程序 创建程序分为以下几个步骤: 1.首先是创建一个 ...

  6. 004 01 Android 零基础入门 01 Java基础语法 01 Java初识 04 Java程序的结构

    004 01 Android 零基础入门 01 Java基础语法 01 Java初识 04 Java程序的结构 Java程序的结构 Java程序外层--类 程序外层,如下面的代码,是一个类的定义. c ...

  7. 003 01 Android 零基础入门 01 Java基础语法 01 Java初识 03 Java程序的执行流程

    003 01 Android 零基础入门 01 Java基础语法 01 Java初识 03 Java程序的执行流程 Java程序长啥样? 首先编写一个Java程序 记事本编写程序 打开记事本 1.wi ...

  8. 学Android开发,入门语言java知识点

    学Android开发,入门语言java知识点 Android是一种以Linux为基础的开源码操作系统,主要使用于便携设备,而linux是用c语言和少量汇编语言写成的,如果你想研究Android,就去学 ...

  9. 黑马程序员----java基础笔记上(毕向东)

    ------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 笔记一共记录了毕向东的java基础的25天课程,分上.中.下 本片为上篇,涵盖前10天课程 1. ...

随机推荐

  1. 每日学习总结<一> 2015-8-31

      Java : 抽象类的简单概念和意义: 包名:域名相反.例: com.eric.test; 访问权限: (public/default/private/protected) public: 可以修 ...

  2. 基于HTML5树组件延迟加载技术实现

    HT for Web的HTML5树组件有延迟加载的功能,这个功能对于那些需要从服务器读取具有层级依赖关系数据时非常有用,需要获取数据的时候再向服务器发起请求,这样可减轻服务器压力,同时也减少了浏览器的 ...

  3. php的<?php ?>标签匹配

    在公司实习了没有多久就开始和同事发现了一个问题,就是之前的人写过的项目经常莫名其妙的出错,仔细的看项目的源代码的时候发现项目中并没有逻辑上的错误,而且各种关系以及数据都没有问题,这是为什么呢.再次认真 ...

  4. BUG集锦

    1.0 jQuery 序列化表单数据 serialize() 得到的是 ""; 表单元素没有name属性.(用的美工的页面,没注意这个细节.)

  5. foreach DataTable或Table时要略过第一行。

    昨天有续写一个练习<输入数字动态创建行(二)>http://www.cnblogs.com/insus/p/4916260.html ,最终是需要把数据存入数据库中. 在循环ASP:Tab ...

  6. 基于MVC4+EasyUI的Web开发框架经验总结(14)--自动生成图标样式文件和图标的选择操作

    在很多Web系统中,一般都可能提供一些图标的选择,方便配置按钮,菜单等界面元素的图标,从而是Web系统界面看起来更加美观和协调.但是在系统中一般内置的图标样式相对比较有限,而且硬编码写到样式表里面,这 ...

  7. 【C#】分享一个可灵活设置边框的Panel

    ---------------------------更新:2014-05-19--------------------------- 优化了一下逻辑,就是既然可以通过设置BorderSide=Non ...

  8. 奔跑的歌颂 diskgenius 找回了20G数据

    2.0同学家的电脑不慎重装系统,结果默认重新分区.其他倒没什么数据,就是几千张记录孩子成长的照片最为珍贵.为了找回数据,用U盘启动,使用Diskgenius全部找回,在此奔歌一下.

  9. python的metaclass

    元类一般用于创建类.在执行类定义时,解释器必须要知道这个类的正确的元类.解释器会先寻找类属性__metaclass__,如果此属性存在,就将这个属性赋值给此类作为它的元类.如果此属性没有定义,它会向上 ...

  10. C#的变迁史 - C# 2.0篇

    在此重申一下,本文仅代表个人观点,如有不妥之处,还请自己辨别. 第一代的值类型装箱与拆箱的效率极其低下,特别是在集合中的表现,所以第二代C#重点解决了装箱的问题,加入了泛型.1. 泛型 - 珍惜生命, ...