安卓端拍照上传服务器+保存到本地电脑

2017-11-21  本文已影响0人  墨色尘埃

项目地址:https://github.com/jihymood/TakePicture
这篇文章讲的很好:Retrofit2文件上传
使用retrofit2+rxjava2
PointApi

public interface PointApi {

    @Multipart
    @POST("New_work_order/uploadFile")
    Observable<ResponseObj<Boolean>> uploadFile(@PartMap Map<String, InputStream> map);

    @Multipart
    @POST("New_work_order/uploadFile")
    Observable<ResponseObj<Boolean>> uploadFile2(@PartMap Map<String, RequestBody> files);

}

MainActivity,主要看onActivityResult方法中的,map里的key必须是file.getName() + ""; filename="" + file.getName(),这样才能在后台的方法中接收到,具体是为什么有待研究

package com.cc.csdndemo1;

import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers;
import okhttp3.MediaType;
import okhttp3.RequestBody;

public class MainActivity extends AppCompatActivity {


    @BindView(R.id.takephotoTV)
    Button takephotoTV;
    @BindView(R.id.savephotoTV)
    Button savephotoTV;
    @BindView(R.id.imageIV)
    ImageView imageIV;

    private final int CAMERA_REQUEST = 8888;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);
    }


    @OnClick({R.id.takephotoTV, R.id.savephotoTV})
    public void onViewClicked(View view) {
        switch (view.getId()) {
            case R.id.takephotoTV:
                Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
                startActivityForResult(cameraIntent, CAMERA_REQUEST);
                break;
            case R.id.savephotoTV:
                getFile();
                break;
        }
    }


    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        Bitmap bitmap = null;
        if (requestCode == CAMERA_REQUEST && resultCode == RESULT_OK) {
            bitmap = (Bitmap) data.getExtras().get("data");
            imageIV.setImageBitmap(bitmap);
        }

        /**
         * Map<String, InputStream>
         * 方法一
         */
        File file = compressImage(bitmap);
        Map<String, InputStream> files = new HashMap<>();
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
        InputStream inputStream = new ByteArrayInputStream(baos.toByteArray());
        files.put(file.getName() + "\"; filename=\"" + file.getName(), inputStream);

        /**
         * Map<String, RequestBody>
         * 方法二:map里的key必须是file.getName() + "\"; filename=\"" + file.getName()这样
         * 这样才能在后台的方法中接收到,具体是为什么有待研究
         */
        Map<String, RequestBody> map = new HashMap<>();
        File file1 = compressImage(bitmap);
        String ext = file1.getName().substring(file1.getName().lastIndexOf(".") + 1);
        RequestBody requestBody = RequestBody.create(MediaType.parse("image/" + ext), file1);
        map.put(file1.getName() + "\"; filename=\"" + file1.getName(), requestBody);


        ApiManager.getInstance()
                .pointApiService()
//                .uploadPicture1(files)
//                .uploadPicture2(map)
                .uploadPicture(map)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new io.reactivex.functions.Consumer<ResponseObj<Boolean>>() {
                    @Override
                    public void accept(ResponseObj<Boolean> booleanResponseObj) throws Exception {
                        Log.e("MainActivity", "booleanResponseObj:" + booleanResponseObj.data.toString());
                    }
                }, new io.reactivex.functions.Consumer<Throwable>() {
                    @Override
                    public void accept(Throwable throwable) throws Exception {
                        Log.e("MainActivity", "throwable:" + throwable);
                    }
                });

    }


    /**
     * 压缩图片(质量压缩)
     *
     * @param bitmap
     */
    public File compressImage(Bitmap bitmap) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);//质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中
        int options = 100;

        //循环判断如果压缩后图片是否大于500kb,大于继续压缩;不进行压缩的话调过这段代码
//        while (baos.toByteArray().length / 1024 > 500) {
//            baos.reset();//重置baos即清空baos
//            options -= 10;//每次都减少10
//            bitmap.compress(Bitmap.CompressFormat.JPEG, options, baos);//这里压缩options%,把压缩后的数据存放到baos中
//            long length = baos.toByteArray().length;
//        }

        SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
        Date date = new Date(System.currentTimeMillis());
        String filename = format.format(date);
        File file = new File(Environment.getExternalStorageDirectory(), filename + ".png");
        try {
            FileOutputStream fos = new FileOutputStream(file);
            try {
                fos.write(baos.toByteArray());
                fos.flush();
                fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        return file;
    }


    /**
     * 选择手机指定目录文件上传到电脑
     */
    public void getFile() {
        FileInputStream fis = null;
        FileOutputStream fos = null;
        File file = null;
        String name = "拍照姿势大全,50条顶级秘籍.txt";
        String path = Environment.getExternalStorageDirectory().getPath() + "/" + name;
        try {
            file = new File(path);
            fis = new FileInputStream(file);
            Log.e("MainActivity", String.valueOf(fis.available()));

            /**
             * 方法一:如果使用InputStream传的话,会丢失大部分数据
             * 测试中,一个2946kb的文件传到后台只有2kb了
             */
            Map<String, InputStream> files = new HashMap<>();
            files.put(name + "\"; filename=\"" + name, fis);

            /**
             * 方法二:使用RequestBody传的话,不会丢失数据,可以正常写到后台
             */
            Map<String, RequestBody> map = new HashMap<>();
            String ext = file.getName().substring(file.getName().lastIndexOf(".") + 1);
            RequestBody requestBody = RequestBody.create(MediaType.parse("image/" + ext), file);
            map.put(file.getName() + "\"; filename=\"" + file.getName(), requestBody);

            ApiManager.getInstance()
                    .pointApiService()
//                    .uploadFile(files)
                    .uploadFile1(map)
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Consumer<ResponseObj<Boolean>>() {
                        @Override
                        public void accept(ResponseObj<Boolean> booleanResponseObj) throws Exception {
                            Log.e("MainActivity", booleanResponseObj.data.toString());
                        }
                    }, new Consumer<Throwable>() {
                        @Override
                        public void accept(Throwable throwable) throws Exception {
                            Log.e("MainActivity", throwable.getMessage());
                        }
                    });


        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

}

后台部分:使用Intellij IDEA+SpringBoot开发
在control 层

package com.jspptd.postal.collectserver.restcontrol;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;


/**
 * Created by LOG on 2017/7/5.
 */
@RestController
@RequestMapping("/takePicture")
public class CollectController {

    private Logger log = LoggerFactory.getLogger(CollectController.class);

    @Value("${destDirName}")
    protected String destDirName;

    /**
     * 文件上传
     */
    @RequestMapping(value = "/uploadPicture", method = RequestMethod.POST)
    ResponseObj<Boolean> uploadPicture(HttpServletRequest request) {
        log.info("进入文件上传逻辑");
        if (request instanceof MultipartHttpServletRequest) {
            try {
                MultipartHttpServletRequest mulRequest = (MultipartHttpServletRequest) request;
                Set<Map.Entry<String, MultipartFile>> set = mulRequest.getFileMap().entrySet();
                Map<String, InputStream> listFile = new LinkedHashMap<>();
                log.info("个数" + Integer.toString(set.size()));
                for (Map.Entry<String, MultipartFile> each : set) {
                    String fileName = each.getKey();
                    MultipartFile file = each.getValue();
                    //这里需要上传FTP
                    try {
                        listFile.put(fileName, file.getInputStream());
                    } catch (Exception ex) {
                        return new ResponseObj<>(false, new Error("文件存储失败"));
                    }
                }

                String formjson = mulRequest.getParameter("content");
                ObjectMapper mapper = new ObjectMapper();
                mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
                mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

//                boolean result = iInstallWorkOrder.upLoadFile(listFile);
                boolean result = true;

                return new ResponseObj<>(result);
            } catch (Exception ex) {
                return new ResponseObj<>(false, new Error(ex.getMessage()));
            }

        } else {
            return new ResponseObj<>(false, new Error("文件上传:数据格式不正确"));
        }
    }


    /**
     * 接收到安卓端传过来的map,将图片保存到本地电脑
     */
    @RequestMapping(value = "/picture", method = RequestMethod.POST)
    public ResponseObj<Boolean> reportCompany(HttpServletRequest request) {
        log.info("进入文件上传逻辑");
        if (request instanceof MultipartHttpServletRequest) {
            MultipartHttpServletRequest mulRequest = (MultipartHttpServletRequest) request;
            Set<Map.Entry<String, MultipartFile>> set = mulRequest.getFileMap().entrySet();

            String photoId = UUID.randomUUID().toString();
            for (Map.Entry<String, MultipartFile> each : set) {
                String fileName = each.getKey();
                String name = each.getValue().getOriginalFilename();
                String suffixal = getSuffixal(name);
                try {
                    writeToLocal(fileName, each.getValue().getInputStream());
                } catch (IOException e) {
                    e.printStackTrace();
                    return new ResponseObj(false, new Error("文件保存失败"));
                }
            }
        }
        return new ResponseObj<>(true, null);
    }

    /**
     * 接收到安卓端传过来的map,将图片保存到本地电脑
     */
    @RequestMapping(value = "/uploadFile", method = RequestMethod.POST)
    public ResponseObj<Boolean> uploadFile(HttpServletRequest request) {
        log.info("进入文件上传逻辑");
        if (request instanceof MultipartHttpServletRequest) {
            MultipartHttpServletRequest mulRequest = (MultipartHttpServletRequest) request;
            Set<Map.Entry<String, MultipartFile>> set = mulRequest.getFileMap().entrySet();

            String photoId = UUID.randomUUID().toString();
            for (Map.Entry<String, MultipartFile> each : set) {
                String fileName = each.getKey();
                String name = each.getValue().getOriginalFilename();
                String suffixal = getSuffixal(name);
                try {
                    writeToLocal(fileName, each.getValue().getInputStream());
                } catch (IOException e) {
                    e.printStackTrace();
                    return new ResponseObj(false, new Error("文件保存失败"));
                }
            }
        }
        return new ResponseObj<>(true, null);
    }


    /**
     * 将InputStream写入本地文件
     * 输入流
     *
     * @throws IOException
     */

    private void writeToLocal(String fileName, InputStream input) throws IOException {
        createDir(destDirName);
        String dirFile = destDirName + fileName;
        int len;
        byte[] bytes = new byte[1024];
        FileOutputStream fos = new FileOutputStream(dirFile);
        while ((len = input.read(bytes)) != -1) {
            fos.write(bytes, 0, len);
            fos.flush();
        }
        fos.close();
        input.close();
        System.out.print("创建成功");
    }

    /**
     * 创建文件夹
     *
     * @param destDirName
     * @return
     */
    public boolean createDir(String destDirName) {
        File dir = new File(destDirName);
        if (dir.exists()) {
            return false;
        }
        if (!destDirName.endsWith(File.separator)) {
            destDirName = destDirName + File.separator;
        }
        //创建目录
        if (dir.mkdirs()) {

            return true;
        } else {

            return false;
        }
    }

    /**
     * 截取图片后缀名
     */
    public String getSuffixal(String name) {
        String str = name.substring(name.length() - 4, name.length());
        return str;
    }

    /**
     * 获取当前时间
     */
    public long getNowTime() {
        return new Date().getTime();
    }

    /**
     * 判断String是否为空
     *
     * @param string
     * @return
     */
    public boolean isEmpty(String string) {
        return null == string || "".equals(string);
    }

}

微信图片_20171121150931.png
多图片上传抓包_副本.png
上一篇下一篇

猜你喜欢

热点阅读