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

 

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连接 获取并下载服务器端图片

  写一个工具类:

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

    public static InputStream getInputStream(String path)
    {
        InputStream inputStream = null;
        HttpURLConnection httpURLConnection = null;

        try
        {
            URL url = new URL(path);
            if (null != url)
            {
                httpURLConnection = (HttpURLConnection) url.openConnection();

                // 设置连接网络的超时时间
                httpURLConnection.setConnectTimeout(5000);

                // 打开输入流
                httpURLConnection.setDoInput(true);

                // 设置本次Http请求使用的方法
                httpURLConnection.setRequestMethod("GET");

                if (200 == httpURLConnection.getResponseCode())
                {
                    // 从服务器获得一个输入流
                    inputStream = httpURLConnection.getInputStream();

                }

            }
        }
        catch (MalformedURLException e)
        {
            e.printStackTrace();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        return inputStream;
    }

 

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

public static void saveInputStream(InputStream inputStream,
            String saveToPath)
    {

        byte[] data = new byte[1024];
        int len = 0;

        FileOutputStream fileOutputStream = null;
        try
        {

            fileOutputStream = new FileOutputStream(saveToPath);
            while (-1 != (len = inputStream.read(data)))
            {

                fileOutputStream.write(data, 0, len);

            }
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        finally
        {
            if (null != inputStream)
            {
                try
                {
                    inputStream.close();
                }
                catch (IOException e)
                {
                    e.printStackTrace();
                }
            }

            if (null != fileOutputStream)
            {

                try
                {
                    fileOutputStream.close();
                }
                catch (IOException e)
                {
                    e.printStackTrace();
                }
            }
        }
    }

 

  完整代码: 

package com.meng.utils;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

public class HttpUtils
{

    public static InputStream getInputStream(String path)
    {
        InputStream inputStream = null;
        HttpURLConnection httpURLConnection = null;

        try
        {
            URL url = new URL(path);
            if (null != url)
            {
                httpURLConnection = (HttpURLConnection) url.openConnection();

                // 设置连接网络的超时时间
                httpURLConnection.setConnectTimeout(5000);

                // 打开输入流
                httpURLConnection.setDoInput(true);

                // 设置本次Http请求使用的方法
                httpURLConnection.setRequestMethod("GET");

                if (200 == httpURLConnection.getResponseCode())
                {
                    // 从服务器获得一个输入流
                    inputStream = httpURLConnection.getInputStream();

                }

            }
        }
        catch (MalformedURLException e)
        {
            e.printStackTrace();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        return inputStream;
    }

    public static void saveInputStream(InputStream inputStream,
            String saveToPath)
    {

        byte[] data = new byte[1024];
        int len = 0;

        FileOutputStream fileOutputStream = null;
        try
        {

            fileOutputStream = new FileOutputStream(saveToPath);
            while (-1 != (len = inputStream.read(data)))
            {

                fileOutputStream.write(data, 0, len);

            }
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        finally
        {
            if (null != inputStream)
            {
                try
                {
                    inputStream.close();
                }
                catch (IOException e)
                {
                    e.printStackTrace();
                }
            }

            if (null != fileOutputStream)
            {

                try
                {
                    fileOutputStream.close();
                }
                catch (IOException e)
                {
                    e.printStackTrace();
                }
            }
        }
    }

}
HttpUtils.java

 

  测试程序: 

package com.meng.learn;


import java.io.InputStream;
import com.meng.utils.HttpUtils;

public class HttpTest
{
    private static String URL_PATH = "http://192.168.11.6:8080/HelloWeb/android.jpg";
    
    public static void main(String[] args)
    {
        InputStream inputStream = HttpUtils.getInputStream(URL_PATH);
        HttpUtils.saveInputStream(inputStream,"D:\\test1.jpg");

    }

}

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

 

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

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

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

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

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

 

需要添加的权限

 

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

 

  布局文件如下:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView
        android:padding="10dp"
        android:id="@+id/info"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="14sp" />

    <Button
        android:id="@+id/btn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Download Image"
        android:textSize="14sp" />

    <ImageView
        android:padding="10dp"
        android:id="@+id/image"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>
activity_image_download.xml

 

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

package com.mengexample.test;

import java.io.InputStream;

import com.windexample.utils.FileUtils;
import com.windexample.utils.HttpUtils;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

public class ImageDownloadActivity extends Activity
{
    private static String URL_PATH = "http://192.168.11.6:8080/HelloWeb/android.jpg";

    private TextView mTextView = null;
    private Button mButton = null;
    private ImageView mImageView = null;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_image_download);

        mTextView = (TextView) findViewById(R.id.info);
        mTextView.setText(URL_PATH);
        mButton = (Button) findViewById(R.id.btn);
        mButton.setOnClickListener(mBtnClickListener);
        mImageView = (ImageView) findViewById(R.id.image);

    }

    private OnClickListener mBtnClickListener = new OnClickListener()
    {

        @Override
        public void onClick(View v)
        {
            // 首先确认网络连接
            ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo networkInfo = connectivityManager
                    .getActiveNetworkInfo();
            if (null != networkInfo && networkInfo.isConnected())
            {
                new DownloadImageTask().execute(URL_PATH);
            }
            else
            {
                Toast.makeText(ImageDownloadActivity.this,
                        "No network connection available", Toast.LENGTH_SHORT)
                        .show();
            }
        }
    };

    private class DownloadImageTask extends AsyncTask<String, Void, Bitmap>
    {

        @Override
        protected Bitmap doInBackground(String... params)
        {
            String path = params[0];

            InputStream inputStream = HttpUtils.getInputStream(path);

            // 从输入流得到位图
            Bitmap bitmap = BitmapFactory.decodeStream(inputStream);

            // 将图像存储到SD卡
            FileUtils.saveToSDCard(bitmap, "TestImage", "android.jpg");

            return bitmap;
        }

        @Override
        protected void onPostExecute(Bitmap result)
        {
            // 将图像显示出来
            mImageView.setImageBitmap(result);
        }

    }

}

  

  其中用到的两个工具类:

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

package com.windexample.utils;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

public class HttpUtils
{

    public static InputStream getInputStream(String path)
    {
        InputStream inputStream = null;
        HttpURLConnection httpURLConnection = null;

        try
        {
            URL url = new URL(path);
            if (null != url)
            {
                httpURLConnection = (HttpURLConnection) url.openConnection();

                // 设置连接网络的超时时间
                httpURLConnection.setConnectTimeout(5000);

                // 打开输入流
                httpURLConnection.setDoInput(true);

                // 设置本次Http请求使用的方法
                httpURLConnection.setRequestMethod("GET");

                if (200 == httpURLConnection.getResponseCode())
                {
                    // 从服务器获得一个输入流
                    inputStream = httpURLConnection.getInputStream();

                }

            }
        }
        catch (MalformedURLException e)
        {
            e.printStackTrace();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        return inputStream;
    }

}

  

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

package com.windexample.utils;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import android.graphics.Bitmap;
import android.os.Environment;
import android.util.Log;

public class FileUtils
{
    private static String TAG = "File";

    public static String getSDCardRootPath()
    {
        // SD卡根目录
        String sDCardRoot = Environment.getExternalStorageDirectory()
                .getAbsolutePath();

        return sDCardRoot;
    }

    public static void saveToSDCard(Bitmap bitmap, String filePath,
            String fileName)
    {

        // 将所给文件路径和文件名与SD卡路径连接起来
        String sdcardRoot = getSDCardRootPath();
        // 创建文件路径
        File dir = new File(sdcardRoot + File.separator + filePath);
        Log.i(TAG, "dir: " + dir);
        if (!dir.exists())
        {
            dir.mkdirs();
        }

        File targetFile = new File(dir, fileName);

        try
        {
            targetFile.createNewFile();
            FileOutputStream fileOutputStream = new FileOutputStream(targetFile);
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fileOutputStream);

            fileOutputStream.flush();
            fileOutputStream.close();
        }
        catch (FileNotFoundException e)
        {
            e.printStackTrace();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }

    }
}

  

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

 

   并且查看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方法发送请求

 

posted @ 2013-06-19 17:51  圣骑士wind  阅读(5292)  评论(0编辑  收藏  举报