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方法發送請求

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM