Android上传头像或上传文件之Retrofit2 使用@Multipart使用标签@PartMap

前言

早上到下午搞了一天的bug
因为突然停电,导致android studio 不能正常运行 所有的项目都不能运行
xml乱码 项目乱码 R文件丢失 等问题!
心态极度崩溃 最后功夫不负有心人 还好解决了

以上文字和博文没有任何牵连 只是被bug搞的很崩溃
再次记录一下

进入正题

后台希望我们传一个file格式的图片 上传到服务器
然后返回一个服务器保存的图片地址 类似这样的格式
/static/images/upload/20200818/ccf0fca9f8c37bed259e0d71707c005c.jpg
最后我们请求接口获取到这个地址 加上服务器域名即可显示这个图片

看下实现效果

请求格式

使用Retrofit2

 @Multipart
    @POST(HttpService.UPLOAD_AVATAR)
    Observable> uploadAvatar(@PartMap Map files, 
    @Part MultipartBody.Part file);

Presenter层代码逻辑实现

  • 1.先实现对参数的封装
 	//创建 RequestBody,用于封装构建RequestBody
    private RequestBody toRequestBody(String value) {
        RequestBody requestBody = RequestBody.create(MediaType.parse("text/plain"), value);
        return requestBody;
    }
  • 2.再操作接口
 /**
     * 上传头像
     *
     * @param path
     */
    @Override
    public void uploadAvatar(String path) {
        //文件格式
        File file = new File(path);
        // 创建 RequestBody,用于封装构建RequestBody
        RequestBody requestFile =
                RequestBody.create(MediaType.parse("multipart/form-data"), file);
        //和后端约定好Key,这里的partName是用file
        MultipartBody.Part body =
                MultipartBody.Part.createFormData("file", file.getName(), requestFile);
        if (UserUtils.getUserInfo() == null) return;
        String userId = UserUtils.getUserInfo().getId() + "";
        String token = StringUtils.getToken();
        Map params = new HashMap<>();
        params.put("user_id", toRequestBody(userId));
        params.put("appid", toRequestBody(APP_ID));
        params.put("token", toRequestBody(token));
        mCompositeDisposable.add(mFullOilApi.uploadAvatar(params, body)
                .subscribeOn(Schedulers.io())
                .doOnSubscribe(new Consumer() {
                    @Override
                    public void accept(Disposable disposable) throws Exception {
                        mCompositeDisposable.add(disposable);
                        mPersonalInfoView.requestStart();
                    }
                })
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer>() {
                    @Override
                    public void accept(BaseBean baseBean) throws Exception {
                        mPersonalInfoView.requestComplete();
                        if (baseBean.getCode() == SUCCESS) {
                            if (UserUtils.getAppConfig() != null) {
                                String apiUrl = UserUtils.getAppConfig().getApp_url();
                                //按照后台要求拼接图片地址
                                String imaUrl = apiUrl + "/static/images/upload/" + baseBean.getData().get(0).getSaveName();
                                mPersonalInfoView.changeUserAvatar(imaUrl);
                            }
                        } else {
                            mPersonalInfoView.showErrorMessage(baseBean.getMessage());
                        }
                    }
                }, new Consumer() {
                    @Override
                    public void accept(Throwable throwable) throws Exception {
                        mPersonalInfoView.showErrorMessage(HttpUtils.getHttpErrorMessage(mContext, throwable));
                        mPersonalInfoView.requestComplete();
                    }
                }));
    }

总结

如此头像上传就完成了 不过上传头像之前需要裁切
我是找的第三方组件

  //裁剪图片
  implementation 'com.github.yalantis:ucrop:2.2.1'

代码实现在这里也贴出来共享一下

//头像裁减
public class CropActivity extends AppCompatActivity {

    public static final String EXTRA_PATH = "extra_path";
    public static final int REQUEST_CODE = 33;
    private Unbinder mUnbinder;
    @BindView(R.id.toolbar)
    Toolbar mToolbar;
    @BindView(R.id.ucropview)
    UCropView mUCropView;
    private GestureCropImageView mCropImage;
    private OverlayView mOverlayView;
    private String mOutputPath;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_crop);
        StatusBarUtils.transparencyBar(this);
        mUnbinder = ButterKnife.bind(this);
        setSupportActionBar(mToolbar);
        getSupportActionBar().setDisplayShowTitleEnabled(false);
        mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                onBackPressed();
            }
        });
        mCropImage = mUCropView.getCropImageView();
        mOverlayView = mUCropView.getOverlayView();
        mCropImage.setTransformImageListener(mCropListener);
        mCropImage.setRotateEnabled(false);
        mOverlayView.setShowCropGrid(false);
        String cacheDir = FileUtils.getAppPath();
        File file = new File(cacheDir, "ucrop_user_avatar.jpg");
        mOutputPath = file.getAbsolutePath();
        Uri destinationUri = Uri.fromFile(file);
        String path = getIntent().getStringExtra(EXTRA_PATH);
        try {
            mCropImage.setImageUri(Uri.parse(path), destinationUri);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_confirm, menu);
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        mCropImage.cropAndSaveImage(Bitmap.CompressFormat.JPEG, 70, new BitmapCropCallback() {
            @Override
            public void onBitmapCropped(@NonNull Uri resultUri, int offsetX, int offsetY, int imageWidth, int imageHeight) {
                Log.e("CropActivity", "裁剪图片成功" + resultUri);
                File file = new File(mOutputPath);
                if (file.exists()) {
                    Log.e("CropActivity", "图片大小" + file.getTotalSpace());
                }
                Intent intent = new Intent();
                intent.putExtra(EXTRA_PATH, mOutputPath);
                setResult(RESULT_OK, intent);
                finish();
            }

            @Override
            public void onCropFailure(@NonNull Throwable t) {
                Log.e("CropActivity", "裁剪图片失败");
            }
        });
        return true;
    }

    private TransformImageView.TransformImageListener mCropListener = new TransformImageView.TransformImageListener() {
        @Override
        public void onRotate(float currentAngle) {
        }

        @Override
        public void onScale(float currentScale) {
        }

        @Override
        public void onLoadComplete() {
            mCropImage.setTargetAspectRatio(1);
            mCropImage.postTranslate(1, 1);
        }

        @Override
        public void onLoadFailure(@NonNull Exception e) {
        }

    };

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mUnbinder.unbind();
    }
}

共勉

我要一步一步往上爬
在最高点乘着叶片往前飞
任风吹干流过的泪和汗
我要一步一步往上爬
等待阳光静静看着它的脸
小小的天有大大的梦想
我有属于我的天
任风吹干流过的泪和汗
总有一天我有属于我的天
Android上传头像或上传文件之Retrofit2 使用@Multipart使用标签@PartMap_第1张图片

你可能感兴趣的:(Android,技术,上传文件,上传头像,Retrofit上传文件,Multipart)