美文网首页
安卓端拍照上传服务器+保存到本地电脑

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

作者: 墨色尘埃 | 来源:发表于2017-11-21 15:57 被阅读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

    相关文章

      网友评论

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

          本文链接:https://www.haomeiwen.com/subject/oarwvxtx.html