今天在做项目的时候做到了上传头像, 但是在做的时候有很多的问题, 发现很多东西自己都是不会的, 都是以前学过的知识,
自己的基本功还是不扎实, 感到了深深地后悔 所以在2019/1/10号晚上8:47分记下自己的在上传头像中所了解到的知识进行累计
并且记录一下自己所踩过的坑:
1.首先先看到自己的布局 ,一个popwindow
这样的布局自己是在网上找的,在自己的文章这里 也有转载
2.弹出这个popwindow之后点击相机和相册 进行隐式跳转 进入相机和相册
//相册获取图片 private void getPicFromAlbm() { Intent photoPickerIntent = new Intent(Intent.ACTION_PICK); photoPickerIntent.setType("image/*"); ((SetupActivity)context).startActivityForResult(photoPickerIntent, 1); } //相机获取图片 private void getPicFromCamera() { tempFile = new File(Environment.getExternalStorageDirectory(), "head.png"); Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(tempFile)); ((SetupActivity)context).startActivityForResult(intent, 2); }
这是进入相机和相册的方法 在点击事件那里点击就可以进入
3.onActivityResult回调方法(这个回调方法中有一个裁剪的方法,下面会上)
//回调方法 public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { switch (requestCode) { case 1: if (resultCode == RESULT_OK) { cropPhoto(data.getData());//裁剪图片 } break; case 2: if (resultCode == RESULT_OK) { File temp = new File(Environment.getExternalStorageDirectory() + "/head.png"); cropPhoto(Uri.fromFile(temp));//裁剪图片 } break; case 3: if (data != null) { Bundle extras = data.getExtras(); if (extras == null) { return; } head = extras.getParcelable("data"); if (head != null) { String fileName = path + "/head.png";//图片名字 setPicToView(head);//保存在SD卡中 File file1 = new File(fileName); doHeadImageHttp(file1); //uploadImage(fileName); } } break; default: break; }
这里是裁剪的方法 //裁剪方法 public void cropPhoto(Uri uri) { Intent intent = new Intent("com.android.camera.action.CROP"); intent.setDataAndType(uri, "image/*"); intent.putExtra("crop", "true"); // aspectX aspectY 是宽高的比例 intent.putExtra("aspectX", 1); intent.putExtra("aspectY", 1); // outputX outputY 是裁剪图片宽高 intent.putExtra("outputX", 127); intent.putExtra("outputY", 127); intent.putExtra("scale", true); intent.putExtra("noFaceDetection", false);//不启用人脸识别 intent.putExtra("return-data", true); ((SetupActivity)context).startActivityForResult(intent,3); }
4.当我们采集完图片后要进行保存图片
这个就是保存图片的方法 private void setPicToView(Bitmap mBitmap) { String sdStatus = Environment.getExternalStorageState(); if (!sdStatus.equals(Environment.MEDIA_MOUNTED)) { // 检测sd是否可用 return; } FileOutputStream b = null; File file = new File(path); file.mkdirs();// 创建文件夹 String fileName = path + "/head.png";//图片名字 try { b = new FileOutputStream(fileName); mBitmap.compress(Bitmap.CompressFormat.JPEG, 100, b);// 把数据写入文件 } catch (FileNotFoundException e) { e.printStackTrace(); } finally { try { //关闭流 b.flush(); b.close(); } catch (IOException e) { e.printStackTrace(); } } }
接下来就是重要的上传头像了
扫描二维码关注公众号,回复:
5760433 查看本文章
接口信息需要传入一个File类型的文件
这里使用的是Retrofit上传图片
@SuppressLint("CheckResult") private void doHeadImageHttp(File file1) { //获取到需要传入的头参进行请求接口 int userId = SharedPreUtils.getInt(context, "userId"); String sessionId = SharedPreUtils.getString(context, "sessionId"); Map<String, String> m = new HashMap<>(); m.put("userId", userId + ""); m.put("sessionId", sessionId); RequestBody file = RequestBody.create(MediaType.parse("multipart/form-data"), file1); MultipartBody.Part part = MultipartBody.Part.createFormData("image", "head.png", file); //这里请求的是一个https 所以要进行信任证书 所以 加了这一步 如果不是HTTPS请忽略 OkHttpClient.Builder builde = new OkHttpClient.Builder() .readTimeout(5, TimeUnit.SECONDS); okHttpClient = new RSAUtils(App.getAppContext()).setCertificateForOkhttp(builde).build(); //开始请求 Retrofit retrofit = new Retrofit.Builder() .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) //添加这个拦截器 .client(okHttpClient) .baseUrl("https://172.17.8.100") .build(); retrofit.create(BaseService.class) .upload("/techApi/user/verify/v1/modifyHeadPic",m, part).subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Consumer<ResponseBody>() { @Override public void accept(ResponseBody responseBody) throws Exception { //这里请求完会返回一个ResponseBody 对象 里面的string方法是一个字符串 进行解析 里面是上传头像成功或者失败的值 UploadEntity uploadEntity = new Gson().fromJson(responseBody.string(),UploadEntity.class); if (uploadEntity.getStatus().equals("0000")){ //这个是得到图片的对象 String result = uploadEntity.getResult(); //在请求成功之后进行设置图片 mImageHead.setImageBitmap(head); Log.i("TAG",""+head); //关闭pop pw.dismiss(); //因为要在前一个页面更新头像所以这里存储一下请求下来的头像地址这里存储的图片要和前一个页面取出图片的key值要一样 一样!! 并且传入的value值一定要是图片的网址!!!(本人粗心大意 传入了Bitmap对象 所以前一个界面和后一个页面的图片只能更新一下 谨记,谨记!!!) SharedPreUtils.put(context,"headPic",result); Toast.makeText(context, ""+uploadEntity.getMessage(), Toast.LENGTH_SHORT).show(); }else{ Toast.makeText(context, ""+uploadEntity.getMessage(), Toast.LENGTH_SHORT).show(); } } }); }
这个是进行网络请求的BaseService
@Multipart
@POST (这里可以传入请求的接口 如果上面写了 ,这里就可以不用写了,(下面的url))
Observable<ResponseBody> upload(@Url String url, @HeaderMap Map<String, String> map,@Part MultipartBody.Part part);
这个是在onResume生命周期里面 重新调用 注:取到的key值一定要和上面存入的key一样!!! String headPic = SharedPreUtils.getString(context, "headPic");