Android|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|Android上传头像或上传文件之Retrofit2 使用@Multipart使用标签@PartMap】我要一步一步往上爬
在最高点乘着叶片往前飞
任风吹干流过的泪和汗
我要一步一步往上爬
等待阳光静静看着它的脸
小小的天有大大的梦想
我有属于我的天
任风吹干流过的泪和汗
总有一天我有属于我的天
文章图片
推荐阅读
- android第三方框架(五)ButterKnife
- Android中的AES加密-下
- 带有Hilt的Android上的依赖注入
- android|android studio中ndk的使用
- Android事件传递源码分析
- RxJava|RxJava 在Android项目中的使用(一)
- Android7.0|Android7.0 第三方应用无法访问私有库
- 深入理解|深入理解 Android 9.0 Crash 机制(二)
- android防止连续点击的简单实现(kotlin)
- Android|Android install 多个设备时指定设备