欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Android通过IO流获取服务器的图片数据

程序员文章站 2022-05-27 08:37:50
...

在Android开发中,经常需要从后台服务器下载图片进行显示。虽然有很多现成的开源框架使用,给定一个url,进行一些配置后,直接就能加载图片显示,缓存都做好了。但是有的场景,例如涉及安全、隐私的场合,不能直接拿一个公开的url使用,还是需要通过原始数据流的方法来获取图片。

通过请求参数,进行一些验证,能提高安全性。这里以最简单的IO流为例,没有涉及到图片缓存。好,废话不多说,直接上代码:

package com.example.downloadpictest;

import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Date;

import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;

public class MainActivity extends Activity {

    private ImageView ivImg;
    private Button btnDownload;
    private Bitmap img;
    private ImageHandler imgHandler = new ImageHandler();
    //测试Url
    private String url = "http://192.168.42.193:8080/DownloadPicTest/servlet/DownloadServlet"; 

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ivImg = (ImageView) findViewById(R.id.ivImg);
        btnDownload = (Button) findViewById(R.id.btnDownload);
        //点击按钮开始下载
        btnDownload.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                downloadImg();
            }
        });
    }

    /**
     * 异步从服务器加载图片数据
     */
    private void downloadImg(){
        new Thread(new Runnable() {
            @Override
            public void run() {
                Bitmap img =  getImg();
                Message msg = imgHandler.obtainMessage();
                msg.what = 0;
                msg.obj = img;
                imgHandler.sendMessage(msg); 
            }
        }).start();
    }

    /**
     * 异步线程请求到的图片数据,利用Handler,在主线程中显示
     */
    class ImageHandler extends Handler{
        @Override
        public void handleMessage(Message msg) {

            switch (msg.what) {
            case 0:
                img = (Bitmap)msg.obj;
                if(img != null){
                    ivImg.setImageBitmap(img);
                }
                break;

            default:
                break;
            }
        }
    }

    /**
     * 从服务器读取图片流数据,并转换为Bitmap格式
     * @return Bitmap
     */
    private Bitmap getImg(){
        Bitmap img = null;

        try {
            URL imgUrl = new URL(url);          
            HttpURLConnection conn = (HttpURLConnection) imgUrl.openConnection();

            conn.setRequestMethod("POST");
            conn.setConnectTimeout(1000 * 6);
            conn.setDoInput(true);
            conn.setDoOutput(true);
            conn.setUseCaches(false);

            conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); 
            conn.setRequestProperty("Connection", "Keep-Alive");
            conn.setRequestProperty("Charset", "UTF-8");
            conn.connect();

            //输出流写参数
            DataOutputStream dos = new DataOutputStream(conn.getOutputStream());
            String param = getParam();
            dos.writeBytes(param);
            dos.flush();
            dos.close();

            int resultCode = conn.getResponseCode();

            if(HttpURLConnection.HTTP_OK == resultCode){
                InputStream is = conn.getInputStream();
                img = BitmapFactory.decodeStream(is);
                is.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        return img;
    }

    /**
     * 测试参数
     * @return 
     */
    private String getParam(){
        JSONObject jsObj = new JSONObject();
        try {
            jsObj.put("picFormat", "jpg");
            jsObj.put("testParam", "9527");
        } catch (JSONException e) {
            e.printStackTrace();
        }

        return jsObj.toString();
    }
}

代码很好理解,就不做过多说明了。注意不要忘了在Manifest中配置网络权限

<uses-permission android:name="android.permission.INTERNET"/>

效果图如下
Android通过IO流获取服务器的图片数据

至于服务器响应图片数据流,可以参考我自己写的一个简单示例: http://blog.csdn.net/ceovip/article/details/79100451