Android使用OkHttp上传/下载多个文件(照片)

我写代码习惯非常不好,可维护性很差,许多地方我也只是调试对了而已,有的是调试时出错,百度了好久找到的问题,其中的原理我也不太懂,欢迎指正。

目录

一.上传文件

二.拍照上传

三.请求网络

四.下载文件

五.Android9以上需要网络配置

六.Android7以上保存文件配置


一.上传文件

1、申请读写权限

2、打开文件管理器

if (ManifestUtil.hasSDK()) {
    Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
    intent.setType("*/*");    // 此处没做文件类型控制,为所有文件类型
    intent.addCategory(Intent.CATEGORY_OPENABLE);
    startActivityForResult(intent, 1);
} else {
    ToastUtil.showMsg("当前设备没有插入sd卡");
}

3、获取返回结果

@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    switch (requestCode) {
        case 1:
            if (resultCode == RESULT_OK) {
                String path;
                File file;
                Uri uri = data.getData();
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                    path = FileUtils.getPath(this, uri);
                } else {
                    path = FileUtils.getRealPathFromURI(this, uri);
                }
                file = new File(path);
                if (StringUtils.isBlank(path)) {
                    ToastUtil.showMsg("地址解析错误,请重新选择");
                } else {    // 我把文件信息都存进model里备用了
                    FileModel model = new FileModel();
                    model.setPath(path);
                    model.setFileName(file.getName());
                    model.setFile(file);
                    mFiles.add(model);
                    notifyListView();    // 上传的文件我用ListView显示,此处为刷新ListView,下同
                }
            }
            break;
    }
}

二.拍照上传

1、申请读写权限

2、打开相机

if (ManifestUtil.hasSDK()) {
    Intent intent = new Intent();
    if (Build.VERSION.SDK_INT >= 24) {
    uri = FileProvider.getUriForFile(this, "包名.fileProvider", file);    // 此处用法详见6
    } else {
        uri = Uri.fromFile(file);
    }
    intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
    intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
    startActivityForResult(intent, C.REQUEST_CODE_PICTURE);
} else {
    ToastUtil.showMsg("当前设备没有插入sd卡");
}

3.获取返回结果

@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    switch (requestCode) {
        case C.REQUEST_CODE_PICTURE:
            if (resultCode == RESULT_OK) {
                try {    // 此照片为原相片,非压缩
                    Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(uri));
                    ImgModel model = new ImgModel();
                    model.setFile(file);
                    model.setImg(bitmap);
                    mBitmaps.add(model);
                    notifyRecyclerView();
                } catch (Exception e) {

                }
            }
            break;
    }
}

三.请求网络

            OkHttpClient client = new OkHttpClient.Builder()
                    .connectTimeout(10, TimeUnit.SECONDS)
                    .readTimeout(10, TimeUnit.SECONDS)
                    .writeTimeout(10, TimeUnit.SECONDS)
                    .build();
            MultipartBody.Builder builder = new MultipartBody.Builder();
            for (FileModel model : list) {
                File file = model.getFile();
                RequestBody body = RequestBody.create(MediaType.parse("multipart/form-data"), file);
//                RequestBody body = RequestBody.create(MediaType.parse("image/jpeg"), file);
                builder.addFormDataPart("fileName", file.getName(), body);
            }
            // 下行是上传的json的对象,其中上面的fileName和下行的fromData需和后台接口名字一致
            builder.addFormDataPart("formData", JsonUtils.toJson(jsonRequest, JsonRequest.class));    
            RequestBody requestBody = builder.setType(MultipartBody.FORM).build();
            final Request request = new Request.Builder()
                    .url("访问地址")
                    .post(requestBody)
                    .build();

            Call call = client.newCall(request);
            call.enqueue(new okhttp3.Callback() {
                @Override
                public void onFailure(Call call, IOException e) {
                }

                @Override
                public void onResponse(Call call, okhttp3.Response response) throws IOException {
                }
            });

四.下载文件

(涉及I/O流,异常可能扔的不对,我写的只在我自己的代码里没问题)

            OkHttpClient client = new OkHttpClient.Builder()
                    .connectTimeout(10, TimeUnit.SECONDS)
                    .readTimeout(10, TimeUnit.SECONDS)
                    .writeTimeout(10, TimeUnit.SECONDS)
                    .build();
            RequestBody requestBody = new MultipartBody.Builder()
                    .setType(MultipartBody.FORM)
                    .addFormDataPart("formData", JsonUtils.toJson(baseRequest, BaseRequest.class))
                    .build();
            final Request request = new Request.Builder()
                    .url("访问地址")
                    .post(requestBody)
                    .build();

            Call call = client.newCall(request);
            call.enqueue(new okhttp3.Callback() {
                @Override
                public void onFailure(Call call, IOException e) {

                }

                @Override
                public void onResponse(Call call, okhttp3.Response response) throws IOException {
                    InputStream inputStream = null;
                    FileOutputStream outputStream = null;
                    try {
                        // 可以解析json获取文件的名字和类型,用于保存文件
                        String json = response.body().string();

                        inputStream = response.body().byteStream();
                        File file = FileUtils.createFile("保存地址");
                        outputStream = new FileOutputStream(file);
                        int i = 0;
                        byte[] bytes = new byte[2048];
                        while ((i = inputStream.read(bytes)) != -1) {
                            outputStream.write(bytes, 0, i);
                        }
                        outputStream.flush();
                    } catch (Exception e) {

                    } finally {
//                        if (inputStream != null && outputStream != null) {
                            inputStream.close();
                            outputStream.close();
//                        }
                    }    
                }
            });

五.Android9以上需要网络配置

1、新建res\xml\network_security_config.xml



    

2、在AndroidManifest.xml的application块中引用

android:networkSecurityConfig="@xml/network_security_config"

六.Android7以上保存文件配置

1、新建res\xml\file_paths.xml



    
    

2.在AndroidManifest.xml的application块中引用


    

3.在使用FileProvider.getUriForFile时引用,如:

Uri uri = FileProvider.getUriForFile(this, "包名.fileProvider", file);

 

你可能感兴趣的:(Android)