okhttp完成头像上传

首先 点击头像的时候 会弹出PopupWindow 所以写好头像的点击事件 之后 去写一个pop的类

public class Pop implements View.OnClickListener{

private Context context = null;
    private PopupWindow popupWindow = null;
    private OnSelectPictureListener listener = null;

    public Pop(Context context, View popview, OnSelectPictureListener listener) {
        this.context = context;
        this.listener = listener;
        View view = LayoutInflater.from(context).inflate(R.layout.popwindow_layout, null);
        initView(view, popview);
    }

    private void initView(View view, View popview) {
        popupWindow = new PopupWindow(popview,
                ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.MATCH_PARENT);
        popupWindow.setContentView(view);
        popupWindow.setBackgroundDrawable(new BitmapDrawable());
        popupWindow.setOutsideTouchable(true);
        popupWindow.setFocusable(true);
        popupWindow.setOutsideTouchable(true);
        popupWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
        popupWindow.showAtLocation(popview, Gravity.BOTTOM, 0, 0);//show()
        view.findViewById(R.id.popup_select_take_photo).setOnClickListener(this);
        view.findViewById(R.id.popup_select_take_picture).setOnClickListener(this);
        view.findViewById(R.id.popup_select_take_cancel).setOnClickListener(this);

    }

    @Override
    public void onClick(View view) {
        int i = view.getId();
        if (i == R.id.popup_select_take_photo) {
            listener.onTakePhoto();

        } else if (i == R.id.popup_select_take_picture) {
            listener.onSelectPicture();

        } else if (i == R.id.popup_select_take_cancel) {
            listener.onCancel();
        }
        //点击完了之后隐藏
        popupWindow.dismiss();
    }


    //点击接口
    public interface OnSelectPictureListener {
        /**
         * 拍摄
         */
        void onTakePhoto();

        /**
         * 从相册选择
         */
        void onSelectPicture();

        /**
         * 取消
         */
        void onCancel();
    }

}

上面类中所用到的布局文件

<LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_above="@+id/share_main_line"
    android:layout_margin="10dp"
    android:background="@drawable/pop_bag"
    android:orientation="vertical">
    <TextView
        android:id="@+id/popup_select_take_photo"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:padding="10dp"
        android:text="拍照"
        android:textColor="#333333"
        android:textSize="16sp" />

    <View
        android:layout_width="match_parent"
        android:layout_height="2dp"
        android:layout_above="@+id/popup_select_take_cancel"
        android:background="#ebebeb" />

    <TextView
        android:id="@+id/popup_select_take_picture"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:padding="10dp"
        android:text="从手机相册选择"
        android:textColor="#333333"
        android:textSize="16sp" />
</LinearLayout>

<View
    android:id="@+id/share_main_line"
    android:layout_width="match_parent"
    android:layout_height="1dp"
    android:layout_marginLeft="19dp"
    android:layout_marginRight="19dp"
    android:layout_above="@+id/popup_select_take_cancel"
    android:background="#ebebeb" />

<TextView
    android:id="@+id/popup_select_take_cancel"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:background="@drawable/pop_bag"
    android:layout_marginLeft="10dp"
    android:layout_marginRight="10dp"
    android:gravity="center"
    android:padding="10dp"
    android:text="取消"
    android:textColor="#333"
    android:textSize="16sp" />

</RelativeLayout>

在这个布局中又用到了 一个自定义shape和一个半透明的颜色

#7f000000 半透明颜色 

<shape xmlns:android="http://schemas.android.com/apk/res/android"
>
<solid android:color="#ffffff"
    />
<corners android:radius="10dp"/>

</shape>

pop 创建完了之后 继续写头像的点击事件

 //弹出PopupWindow
private void tanpop() {
    //先去创建一个pop的工具类
    //new 调用pop工具类 括号里传上下文和本页面布局整体的id new 接口提示
    new Pop(context, chage_pop, new Pop.OnSelectPictureListener() {
        @Override
        public void onTakePhoto() {
            //new 意图跳转相机 mediastore .相机
            Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            //意图传值mediastor .ex  ,uri.fromfile括号new文件传获取系统路径传文件名
            intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(Environment.getExternalStorageDirectory(), pic)));
            //回调方法跳转相机强转本页面0 回调方法写在Activity 调用方法生成过来
            ((LoginLastActivity) context).startActivityForResult(intent, 1);
        }

        @Override
        public void onSelectPicture() {
            //new 意图跳转相册
            Intent intent = new Intent(Intent.ACTION_PICK, null);
            //意图设置dataAnd Type mediastore images.media .ex ,imgae/*通配符
            intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
            //带值跳转1
            ((LoginLastActivity) context).startActivityForResult(intent, 0);
        }

        @Override
        public void onCancel() {
            //取消方法不用写
        }
    });
}

pop的类中有三个接口 分别是相机相册取消 上面 已经写好了实现接口
和activity的带值跳转 下面该做的是 写activity的回调方法 因为这里用的是themvp 所以需要去该页面的Activity中写onActivityResult

//回调方法
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    //判读requestcode
    switch (requestCode){
        case 0:
            //当时0的时候调用方法生成到persenter 传resultcode 和data相机回调
            delegate.onCode0(resultCode,data);
            break;
        case 1:
            //当时0的时候调用方法生成到persenter 传resultcode 相册回调
            delegate.onCode1(resultCode);
            break;
        case 2:
            //当时0的时候调用方法生成到persenter 传rdata 裁剪回调
            delegate.onCode2(data);
            break;
    }
}

persenter里的具体实现方法

//生成过来的方法相机
public void onCode0(int resultCode, Intent data) {
    //判断code==RESULT _OK
    if (resultCode == RESULT_OK) {
        //调用裁剪的方法
        cropPhoto(data.getData());
    }
}

// 相册回调
public void onCode1(int resultCode) {
    //判断code==RESULT _OK
    if (resultCode == RESULT_OK) {
        //new 文件
        File file = new File(Environment.getExternalStorageDirectory() + "/head.png");
        //调用裁剪方法传file URI 调用filefromfile
        cropPhoto(Uri.fromFile(file));
    }
}

  //裁剪回调方法
    public void onCode2(Intent data) {
//        Toast.makeText(context,"哈哈"+data,Toast.LENGTH_SHORT).show();
    //先判断data非空
    if (data != null) {
        //data 获取extras 返回值
        Bundle extras = data.getExtras();
        //判断等于空直接返回
        if (extras == null) {
            return;
        }
        //extras .获取p传引号data返回值head  提上去Bitmap类型
        head = extras.getParcelable("data");
        //判断判断head非空
        if (head != null) {
            //给头像设置imagebitmap 传head
//                last_tou.setImageBitmap(head);
//                //上面封装的固定路径+引号/+pic图片名
            String fileNname = path + "/" + pic;
//                调用储存sd卡的方法 传head
            setPicToView(head);
            //调用ok上传 传个filename
            Log.i("上传的时候",fileNname);
            uploadImage(fileNname);
            //重新保存头像的方法
            setIcon();
        }
    }
  }

在回调具体方法里 又用到了 裁剪储存sd卡okhttp上传头像重新保存头像的方法

裁剪

//裁剪回调方法
public void onCode2(Intent data) {
//        Toast.makeText(context,"哈哈"+data,Toast.LENGTH_SHORT).show();
    //先判断data非空
    if (data != null) {
        //data 获取extras 返回值
        Bundle extras = data.getExtras();
        //判断等于空直接返回
        if (extras == null) {
            return;
        }
        //extras .获取p传引号data返回值head  提上去Bitmap类型
        head = extras.getParcelable("data");
        //判断判断head非空
        if (head != null) {
            //给头像设置imagebitmap 传head
//                last_tou.setImageBitmap(head);
//                //上面封装的固定路径+引号/+pic图片名
            String fileNname = path + "/" + pic;
//                调用储存sd卡的方法 传head
            setPicToView(head);
            //调用ok上传 传个filename
            Log.i("上传的时候",fileNname);
            uploadImage(fileNname);
            //重新保存头像的方法
            setIcon();
        }
    }
}

储存sd卡

 //储存sd卡的方法
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();
        }
    }
   }

okhttp上传头像
如果需要换网址 记得在new Request.Builder()的里面更换网址

 //okhttp上传头像
private void uploadImage(String path) {
    MediaType mediaType = MediaType.parse("multipart/form-data; charset=utf-8");
    OkHttpClient mOkHttpClent = new OkHttpClient();
    File file = new File(path);
    MultipartBody.Builder builder = new MultipartBody.Builder()
            .setType(mediaType)
            .addFormDataPart("file", pic,
                    RequestBody.create(MediaType.parse("image/png"), file))
            .addFormDataPart("uid", uid);

    RequestBody requestBody = builder.build();
    Request request = new Request.Builder()
            .url("网址")
            .post(requestBody)
            .build();
    Call call = mOkHttpClent.newCall(request);
    call.enqueue(new Callback() {
        @Override
        public void onFailure(Call call, final IOException e) {
            ((LoginLastActivity) context).runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    Log.i("TAG", e.getMessage());
                    Toast.makeText(context, "失败", Toast.LENGTH_SHORT).show();
                }
            });
        }

        @Override
        public void onResponse(Call call, Response response) throws IOException {
            ((LoginLastActivity) context).runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    Toast.makeText(context, "更换成功", Toast.LENGTH_SHORT).show();

                }
            });
        }
    });
}

重新保存头像的方法
这个方法 就是 又重新请求了一次服务端 用来更新本地sp中缓存的头像
顺便给本页面的头像控件赋值

 //重新保存头像的方法
private void setIcon() {
    //传一个uid就可以
    HashMap<String, String> map = new HashMap<>();
    map.put("uid", uid);
    RetrofitUtils.getRetrofitUtils().get(url, map).result(new RetrofitUtils.RetrofitListener() {
        @Override
        public void success(String s) {
            //解析读取出来的s
            UserBean userBean = new Gson().fromJson(s, UserBean.class);
            //获取头像
            //储存到sp里面
            //往sp里存东西  昵称写在下面判断和icon to字符串  或者加个空字符串
            SharedPreferences sp = context.getSharedPreferences("config", Context.MODE_PRIVATE);
            sp.edit().putString("icon",userBean.getData().getIcon()).commit();
            Log.i("储存的图",userBean.getData().getIcon());
            //重新给图片赋值
            String s1 = path + "/" + pic;
            last_tou.setImageBitmap(BitmapFactory.decodeFile(s1));
        }

        @Override
        public void fail() {
        //网络错误
            Toast.makeText(context,"网络竟然崩溃了",Toast.LENGTH_SHORT).show();
        }
    });
}

在以上的方法中 用到的几个封装变量

private String pic = "head.png";
private Bitmap head;
//封装一个固定路径
private static String path = "/sdcard/myHead/";//sd路径
登陆成功的uid 在this.uid=uid在Activity  onResume方法里面更新数据生成在persenter的方法里获取uid提上去
private String uid;
//获取用户信息的接口
private String url = "网址";

猜你喜欢

转载自blog.csdn.net/qq_43143884/article/details/84347181