Android的图片上传

今天说一下我的图片上传方法,整体思路是自己拼写出一个html页面,然后使用post的方法将图片传到后台。


上传的执行不会在主线程中,所以我们新起一个线程,并用Handler将信息回传到主线程


    private void uploadImage() {
        new Thread(uploadImageRunnable).start();
        //这里可以显示进度条
    }

    Runnable uploadImageRunnable = new Runnable() {
        @Override
        public void run() {
            Message resultMessage = new Message();
            resultMessage.what = 0;
            //上传图片后回传的结果会储存在 resultMessage.obj 中

            try {

                //TODO 上传图片以及附加信息

            } catch (Exception e) {
                e.printStackTrace();
            }

            handler.sendMessage(resultMessage);
        }
    };

    Handler handler = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(Message msg) {
            switch (msg.what) {
                case 0:
                    //这里可以让进度条消失
                    try {

                        //TODO 处理回传结果

                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                default:
                    break;
            }
            return false;
        }
    });


接下来我来说说“上传图片及附加信息”部分该如何完成


首先新建URL对象(注意这里是https,所以后面会设置SSL的相关信息)

URL url = new URL("https://......");

然后建立连接的对象

HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
设置连接对象的各种属性

                conn.setConnectTimeout(5000);
                conn.setDoOutput(true);
                conn.setRequestMethod("POST");
                conn.setUseCaches(false);
                conn.setRequestProperty("Charset", "UTF-8");
                conn.setRequestProperty("ser-Agent", "Fiddler");
                conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + MyUpLoadUtils.BOUNDARY);

MyUpLoadUtils.BOUNDARY是个分割线,这个大家可以自行寻找下html的拼写方法,这里我就不多说了,它的值如下(随意设置的)

public static final String BOUNDARY = "--my_boundary--";


然后要说SSL协议的设置了,这里有两个东西要设置,一是HostnmaeVerifier,连接地址的验证,二是SSLSocketFactory,这个是二次握手什么的,深入的我也没研究,也是学别人的编写方式编写的,我是在StackOverFlow上学的......


                HostnameVerifier hnv = new HostNameVerifier();
                conn.setHostnameVerifier(hnv);
                SSLContext sslcontext = SSLContext.getInstance("TLS");
                sslcontext.init(null, new TrustManager[]{new X509TrustManagerImpl()}, null);
                conn.setSSLSocketFactory(sslcontext.getSocketFactory());

HostNameVerifier 继承 AbstractVerifier,重写verify方法。

X509TrustManagerImpl 实现 javax.net.ssl.X509TrustManager接口,大家可以自己查查。


好了,设置完连接的各种属性,我们开始传输东西,首先获取输出流对象

                OutputStream os = conn.getOutputStream();
                DataOutputStream ds = new DataOutputStream(os);
然后开始输出,这里我用自己的方法包装了一下

                MyUpLoadUtils.writeStringParams(textParams, ds);
                MyUpLoadUtils.writeBytes(imageBytes, textParams.get("fileName"), ds);
                MyUpLoadUtils.paramsEnd(ds);
textParams是个Map,里面有附加的一些文字信息,imageBytes是图片的二进制数组,具体方法实现如下

    /**
     * 普通字符串数据
     */
    public static void writeStringParams(Map<String, String> textParams, DataOutputStream ds) throws Exception {
        Set<String> keySet = textParams.keySet();
        for (Iterator<String> it = keySet.iterator(); it.hasNext(); ) {
            String name = it.next();
            String value = textParams.get(name);
            ds.writeBytes("--" + BOUNDARY + "\r\n");
            ds.writeBytes("Content-Disposition: form-data; name=\"" + name + "\"\r\n");
            ds.writeBytes("\r\n");
            value = value + "\r\n";
            ds.write(value.getBytes());
        }
    }

    /**
     * 文件数据
     */
    public static void writeBytes(byte[] imageBytes, String fileName, DataOutputStream ds) throws Exception {
        ds.writeBytes("--" + BOUNDARY + "\r\n");
        ds.writeBytes("Content-Disposition: form-data; name=\"" + "uploadFile" +
                "\"; filename=\"" + fileName + "\"\r\n");
        ds.writeBytes("Content-Type:application/octet-stream; charset=utf-8 \r\n");
        ds.writeBytes("\r\n");
        ds.write(imageBytes);
        ds.writeBytes("\r\n");
    }

    /**
     * 添加结尾数据
     */
    public static void paramsEnd(DataOutputStream ds) throws Exception {
        ds.writeBytes("--" + BOUNDARY + "--" + "\r\n");
        ds.writeBytes("\r\n");
    }

别忘记关闭输出流对象

os.close();
然后我们获取服务器的响应信息

                int code = conn.getResponseCode();
                if (code == 200) {// 返回的响应码200,是成功
                    // 得到网络返回的输入流
                    InputStream is = conn.getInputStream();
                    resultMessage.obj = MyUpLoadUtils.readString(is);
                } else {
                    ToastUtils.show("请求URL失败!");
                }

readString方法如下:

    public static String readString(InputStream is) {
        byte[] result = readBytes(is);
        if(result != null){
            return new String(result);
        }else{
            return "";
        }
    }

    private static byte[] readBytes(InputStream is) {
        try {
            byte[] buffer = new byte[1024];
            int len = -1;
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            while ((len = is.read(buffer)) != -1) {
                baos.write(buffer, 0, len);
            }
            baos.close();
            return baos.toByteArray();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


以上是“上传图片及附加信息”部分,放在try{}catch中,最后我们把回传的信息通过Handler传入主线程中

handler.sendMessage(resultMessage);

最后,在主线程中用Gosn解析,处理回传结果

                        String result = (String) msg.obj;
                        Log.e(TAG, result);
                        JSONObject jsonObject = new JSONObject(result);
                        Gson gson = new Gson();
                        XXXXX item = gson.fromJson(result, XXXXX.class);
						
			//TODO 处理回传信息

以上就是我的上传图片方法。









  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值