Android 上传图片或视频

1.通过OkhttpClient上传,首先添加OKHTTP的依赖

implementation 'com.squareup.okhttp3:okhttp:3.13.1'
//selImageList 图片或视频的地址路径 
//此处图片和视频的命名规则为 VID_+时间+.mp4 ,IMG_+时间+.jpg
//此处图片和视频的路径如:/storage/emulated/0/DCIM/Camera/IMG_20200323_135044.jpg
private void uploadMp4OrJpg(ArrayList<ImageItem> selImageList) {

    if(selImageList == null)
        throw new IllegalStateException("selImageList is null");
    
    OkHttpClient okHttpClient = OkHttpUtil.getInstance();

    for (int i = 0; i < selImageList.size(); i++) {
        String path = selImageList.get(i).path;
        path = path.replace("/storage/emulated/0/DCIM/Camera/","");
        File file = null;
        MultipartBody.Builder builder = null;
        if("VID_".equals(s.substring(0,4))){//当前要上传的是视频
            file = new File("/storage/emulated/0/DCIM/Video/"+s); //根据路径创建file对象
            builder = new MultipartBody.Builder()
                .setType(MultipartBody.FORM) //按表单上传文件
                .addFormDataPart(
                        "files",
                        file.getName(),
                        createCustomRequestBody(//自定义requestbody
                                MediaType.parse("application/octetstream"),
                                file,
                                new ProgressListener(){//文件上传进度监听
                                    @Override
                                    public void onProgress(
                                        long totalBytes,
                                        long remainingBytes,
                                        boolean done
                                    ){
                                        Logs.i(""+(int)((totalBytes - remainingBytes) * 100 / totalBytes));//当前上传的进度 1-100;
                                    }
                                }
                                
                        ));
        
        }else{//上传图片
            file = new File(selImageList.get(i).path);
            builder = new MultipartBody.Builder()
                    .setType(MultipartBody.FORM) //按表单上传文件
                    .addFormDataPart(
                            "files",
                            file.getName(),
                            RequestBody.create(//不对上传文件的进度进行监听
                                    MediaType.parse("image/jpeg"), 
                                    file
                            )
                    );
        }
        //post 添加一些参数,后台通过request.getParameter("key1").toString() 取出
        builder.addFormDataPart("key1",value1);
        builder.addFormDataPart("key2",value2);
        RequestBody requestBody = builder.build();

        Request request = new Request.Builder()
                .url("接口路径")
                .header("Cookie", CacheUtil.Cookie)
                .post(requestBody)
                .build();
        Call call = okHttpClient.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Logs.i("上传"+"失败: " + e);
            }
            @Override
            public void onResponse(Call call, 
                okhttp3.Response response) throws IOException {
                Logs.i("上传"+"成功");
                String json = response.body().string();
                Logs.i("response.body()"+json);
            }
        });
    
    }

}

2.自定义requestbody监听上传进度

public RequestBody createCustomRequestBody(
    final MediaType contentType, 
    final File file, 
    final ProgressListener listener) {
        return new RequestBody() {
                    @Override 
                    public MediaType contentType() {
                        return contentType;
                    }

                    @Override 
                    public long contentLength() {
                        return file.length();
                    }

                    @Override
                    public void writeTo(BufferedSink sink) throws IOException {
                        Source source;
                        try {
                            source = Okio.source(file);
                            //sink.writeAll(source);
                            Buffer buf = new Buffer();
                            Long remaining = contentLength();
                            for (long readCount; 
                                (readCount = source.read(buf, 2048)) != -1; ) {
                                    sink.write(buf, readCount);
                                    listener.onProgress(contentLength(), remaining -= readCount, remaining == 0);

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

3.进度监听接口

interface ProgressListener {
    void onProgress(long totalBytes, long remainingBytes, boolean done);
}

4.okhttpclient封装的工具类

import java.util.concurrent.TimeUnit;

import okhttp3.ConnectionPool;
import okhttp3.OkHttpClient;

public class OkHttpUtil {

    private final static int READ_TIMEOUT = 100;

    private final static int CONNECT_TIMEOUT = 60;

    private final static int WRITE_TIMEOUT = 60;

    private static volatile OkHttpClient okHttpClient;

    private OkHttpUtil(){

        okhttp3.OkHttpClient.Builder clientBuilder = new okhttp3.OkHttpClient.Builder();
        //读取超时
        clientBuilder.readTimeout(READ_TIMEOUT, TimeUnit.SECONDS);
        //连接超时
        clientBuilder.connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS);
        //写入超时
        clientBuilder.writeTimeout(WRITE_TIMEOUT, TimeUnit.SECONDS);
        //自定义连接池最大空闲连接数和等待时间大小,否则默认最大5个空闲连接
        clientBuilder.connectionPool(new ConnectionPool(32,5,TimeUnit.MINUTES));

        okHttpClient = clientBuilder.build();
    }

    public static OkHttpClient getInstance(){
        if (null == okHttpClient){
            synchronized (OkHttpUtil.class){
                if (okHttpClient == null){
                    new OkHttpUtil();
                    return okHttpClient;
                }
            }
        }
        return okHttpClient;
    }
}

5.后台接收

@RequestMapping(value = "/saveFiles",method = RequestMethod.POST)
@ResponseBody
public Map saveFile(HttpServletRequest request,HttpServletResponse response){
    Map<String, Object> map = new HashMap<>();
    List<MultipartFile> files = ((MultipartHttpServletRequest)request)
                               .getFiles("files");
   
    MultipartFile file = null;
    BufferedOutputStream stream = null;
    for (int i = 0; i < files.size(); ++i) {
        file = files.get(i);
        if (!file.isEmpty()) {
            try {
                FileBean fileBean=new FileBean();
                //取出post请求的参数
                fileBean.setUserid(request.getParameter("key1").toString());

                fileBean.setFfname(request.getParameter("key2").toString());
                fileBean.setFfileid(UUID.randomUUID().toString());
                //此处是将接收到的图片或视频存放到了数据库中,也可以保存到服务器的某个路径下
                fileService.save(fileBean, file.getInputStream());
                map.put("resultcode", "200");
            } catch (Exception e) {
                e.printStackTrace();
                stream = null;
                map.put("resultcode", "100");
            }
        } else {
            map.put("resultcode", "100");
        }
    }

    return map;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

chailongger

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值