您的位置:首页 > 理论基础 > 计算机网络

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

2013-06-19 20:59 866 查看

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方法发送请求
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐