1.接口文档
更新头像【完成】
请求URL:http://{服务器地址}/api/photo
方法:POST
参数:
参数 |
类型 |
状态 |
备注 |
managerid |
int |
Y |
用户id |
file |
File |
Y |
头像文件 |
返回:
参数 |
类型 |
备注 |
reason |
string |
返回消息 |
result_code |
int |
状态 |
2.界面功能
- app的Gradle中添加
implementation'com.yanzhenjie:permission:2.0.0-rc4'
case R.id.rv_touxiang:
AndPermission.with(getActivity())
.permission(Permission.CAMERA)
.rationale(mRationale)
.onGranted(new Action() {
@Override
public void onAction(List<String>permissions) {
// TODO what to do.
showPop();
}
}).onDenied(new Action() {
@Override
public void onAction(List<String>permissions) {
if (AndPermission.hasAlwaysDeniedPermission(context, permissions)){
// 这些权限被用户总是拒绝。
// 这里使用一个Dialog展示没有这些权限应用程序无法继续运行,询问用户是否去设置中授权。
final SettingService settingService = AndPermission.permissionSetting(mContext);
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("温馨提醒");
builder.setMessage("建议打开您的相机权限,否则无法继续");
builder.setNegativeButton("取消",new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterfacedialog, int which) {
// 如果用户不同意去设置:
settingService.cancel();
}
});
builder.setPositiveButton("确定",new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterfacedialog, int which) {
// 如果用户同意去设置:
settingService.execute();
}
});
AlertDialog dialog = builder.create();
dialog.show();
}
}
})
.start();
break;
private Rationale mRationale = new Rationale() {
@Override
public void showRationale(Context context, List<String> permissions,
final RequestExecutor executor) {
// 这里使用一个Dialog询问用户是否继续授权。
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("温馨提醒");
builder.setMessage("建议打开您的相机权限");
builder.setNegativeButton("取消",new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterfacedialog, int which) {
// 如果用户中断:
executor.cancel();
}
});
builder.setPositiveButton("确定",new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterfacedialog, int which) {
// 如果用户继续:
executor.execute();
}
});
AlertDialog dialog = builder.create();
dialog.show();
}
};
private void showPop() {
cameraPopu = new CameraPopu(getActivity(), new View.OnClickListener(){
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.camera:
String state =Environment.getExternalStorageState();
if (state.equals(Environment.MEDIA_MOUNTED)) {
createNewFile();
Intent getImageByCamera = new Intent("android.media.action.IMAGE_CAPTURE");
getImageByCamera.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file_photo));
startActivityForResult(getImageByCamera, REQUEST_CODE_CAMERA);
} else{
Toast.makeText(getActivity(), "请确认已经插入SD卡", Toast.LENGTH_LONG).show();
}
cameraPopu.dismiss();
break;
case R.id.photo:
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType("image/*");
startActivityForResult(intent, REQUEST_CODE_PHOTO);
cameraPopu.dismiss();
break;
case R.id.cancle:
cameraPopu.dismiss();
break;
}
}
});
cameraPopu.showAtLocation(root, Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0, 0);
}
@Override
public void onActivityResult(int requestCode,int resultCode, Intentdata) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
//相机
case REQUEST_CODE_CAMERA:
if(resultCode== RESULT_OK){
/*
* 默认情况下,即不需要指定intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);照相机有自己默认的存储路径,拍摄的照片将返回一个缩略图。如果想访问原始图片,可以通过dat extra能够得到原始图片位置。即,如果指定了目标uri,data就没有数据,如果没有指定uri,则data就返回有数据!*/
Uri uri = Uri.fromFile(file_photo);
startActivityForResult(cropImageUri(uri, 480, 480), 103);
}
break;
// 相册
case REQUEST_CODE_PHOTO:
if (data!= null) {
Uri uri1 =data.getData();
startActivityForResult(cropImageUri(uri1, 480, 480), 103);
}
break;
//裁剪
case 103:
if (resultCode== RESULT_OK) {
if (data != null) {
// 读取uri所在的图片
if (Uri.fromFile(file_photo) != null) {
rv_touxiang.destroyDrawingCache(); // 上传成功以后,清除图片缓存
Glide.with(this)
.load(Uri.fromFile(file_photo))
.error(R.mipmap.head_portrait)
.into(rv_touxiang);
// 上传头像到服务器
userPresenter.uploadImg(managerId, file_photo, this);
}
}
}
break;
}
}
3.连接后台
public void uploadImg(int managerId,FileimgFile, final UserCenterMvpView userCenterMvpView) {
Map<String, RequestBody>params = RetrofitParameterBuilder.newBuilder()
.addParameter("file", imgFile)
.bulider();
retrofitHelper.toSubscribe(req.uploadUserImg(managerId,params), new Subscriber<KongBean>() {
@Override
public void onCompleted() {
Log.d("dddd", "success");
userCenterMvpView.onGetDataCompleted();
}
@Override
public void onError(Throwable e) {
Log.d("dddd", e.toString());
userCenterMvpView.onGetDataError(e);
}
@Override
public void onNext(KongBeanemptyMessage) {
Log.d("dddd", "successd");
userCenterMvpView.uploadImg(emptyMessage);
}
});
}
Util类:
import android.content.Intent; import android.graphics.Bitmap; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Bundle; import android.os.Environment; import android.provider.MediaStore; import android.text.format.DateFormat; import android.util.Base64; import android.util.Log; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.util.Calendar; import java.util.Locale; /** * Created by Administrator on 2017/10/9. */ public class ImageUtils { public static String capturePath; public static File file_photo; /* *创建一个.jpg文件 */ public static void createNewFile() { capturePath = Environment.getExternalStorageDirectory()+ "/" + DateFormat.format("yyyyMMddhhmmss", Calendar.getInstance(Locale.CHINA)) + ".jpg"; file_photo = new File(capturePath); try { if(file_photo.exists()) { file_photo.delete(); } file_photo.createNewFile(); } catch (IOException e) { e.printStackTrace(); } } // 裁剪图片 public static Intent cropImageUri(Uri uri, int outputX, int outputY) { createNewFile(); Uri crop_Uri = Uri.fromFile(file_photo); Intent intent = new Intent("com.android.camera.action.CROP"); intent.setDataAndType(uri, "image/*"); intent.putExtra("crop", "true"); //裁剪框比例 intent.putExtra("aspectX",outputX); intent.putExtra("aspectY",outputY); //图片输出大小 intent.putExtra("outputX", outputX); intent.putExtra("outputY", outputY); intent.putExtra("scale", true); intent.putExtra(MediaStore.EXTRA_OUTPUT, crop_Uri); return intent; } public void setPicToView(Intent intent) { Bundle extras = intent.getExtras(); if (extras != null) { Bitmap photo = extras.getParcelable("data"); Log.i("SS", photo.toString()); // * 获得图片 // iv_touxiang.setImageBitmap(photo); Drawable drawable = new BitmapDrawable(photo); // draw转换为String ByteArrayOutputStream stream = new ByteArrayOutputStream(); photo.compress(Bitmap.CompressFormat.JPEG, 60, stream); byte[] b = stream.toByteArray(); /* Glide.with(this) .load(b) .error(R.mipmap.my_photo0) .into(iv_touxiang);*/ // updateHeadToReserver(Bitmap2StrByBase64(photo)); } } public String Bitmap2StrByBase64(Bitmap bit){ ByteArrayOutputStream bos=new ByteArrayOutputStream(); bit.compress(Bitmap.CompressFormat.JPEG, 40, bos);//参数100表示不压缩 byte[] bytes=bos.toByteArray(); return Base64.encodeToString(bytes, Base64.NO_WRAP); } /** * 将file文件转化为byte数组 * * @param filePath * @return */ public static byte[] getBytes(String filePath) { byte[] buffer = null; try { File file = new File(filePath); FileInputStream fis = new FileInputStream(file); ByteArrayOutputStream bos = new ByteArrayOutputStream(1000); byte[] b = new byte[1000]; int n; while ((n = fis.read(b)) != -1) { bos.write(b, 0, n); } fis.close(); bos.close(); buffer = bos.toByteArray(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return buffer; } }
4.布局
<com.makeramen.roundedimageview.RoundedImageView
android:id="@+id/rv_touxiang"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_centerHorizontal="true"
android:layout_marginTop="20dp"
android:scaleType="fitXY"
android:src="@mipmap/head_portrait"
app:riv_border_color="@color/white"
app:riv_border_width="2dip"
app:riv_oval="true" />
app的gradle
compile 'com.makeramen:roundedimageview:2.3.0'