mvp+retrofit+okhttp 上传头像

本文介绍了如何结合MVP架构、Retrofit网络库和OkHttp,实现应用程序中上传头像的功能。包括依赖配置、权限申请、接口定义、契约类创建、Presenter逻辑处理以及在MainActivity中的具体实现和相机相册选择的弹框布局。
摘要由CSDN通过智能技术生成

依赖

  implementation 'com.squareup.retrofit2:retrofit:2.4.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
    implementation 'com.facebook.fresco:fresco:1.12.1'
    implementation 'com.facebook.fresco:drawee:1.12.1'
    implementation 'com.facebook.fresco:imagepipeline:1.12.1'
    //rxjava2
    implementation 'com.squareup.retrofit2:adapter-rxjava2:2.4.0'
    //logging-interceptor
    implementation 'com.squareup.okhttp3:logging-interceptor:3.10.0'
    implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'
    implementation 'com.squareup.retrofit2:adapter-rxjava2:2.4.0'
    implementation 'com.squareup.retrofit2:adapter-rxjava:2.0.0-beta4'

权限

  <uses-permission android:name="android.permission.CAMERA"/>
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

接口 Api
public static final String BASE_URL="https://mobile.bwstudent.com/"; public static final String CHUAN="techApi/user/verify/v1/modifyHeadPic";

接口 ApiService

public interface ApiService
{
    //上传头像
    @POST(Api.CHUAN)
    @Multipart
    Observable<UpdateHeadPicBean> updateHeadPic(@HeaderMap HashMap<String ,String> hashMap, @Part MultipartBody.Part parts);
}

bean类省略了

契约类

public interface Contract
{
    /**
     * 上传头像
     */
    public interface IUpdateHeadPicView {

        void onIUpdateHeadPicSuccess(Object o);

        void onIUpdateHeadPicFail(String errorInfo);

    }

    public interface IUpdateHeadPicPre {

        void onIUpdateHeadPicPre(HashMap<String, String> hashMap, File file);

    }

}

p层 presenter

public class ChuanPresenter extends BasePresenter2<MainActivity> implements Contract.IUpdateHeadPicPre {
    @Override
    public void onIUpdateHeadPicPre(HashMap<String, String> hashMap, File file) {
        ApiService apiService = RetrofitUtils.getInstance().create(ApiService.class);
        RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), file);
        MultipartBody.Part filePart=MultipartBody.Part.createFormData("image",file.getName(),requestFile);
        apiService.updateHeadPic(hashMap,filePart)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new DisposableObserver<UpdateHeadPicBean>() {
                    @Override
                    public void onNext(UpdateHeadPicBean value) {
                      getView().onIUpdateHeadPicSuccess(value);
                    }
                    @Override
                    public void onError(Throwable e) {
                        Log.e("lallalal","失败了");
                    }
                    @Override
                    public void onComplete() {

                    }
                });
    }
}

主代码 布局

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <ImageView
        android:id="@+id/img"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
       android:src="@drawable/ic_launcher_background"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>

MainActivity

public class MainActivity extends AppCompatActivity implements Contract.IUpdateHeadPicView {

    private ChuanPresenter chuanPresenter;
    private HashMap<String, String> hashMap;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //网络动态权限
        stateNetWork();
        chuanPresenter = new ChuanPresenter();
        hashMap = new HashMap<>();
        String userId="130";
        String sessionId="1556970635419130";
        hashMap.put("userId",userId);
        hashMap.put("sessionId",sessionId);
        findViewById(R.id.img).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                final Dialog dialog = new Dialog(MainActivity.this);
                //填充对话框的布局
                View inflate = LayoutInflater.from(MainActivity.this).inflate(R.layout.dialog_layout, null);
                //初始化控件
                //相册
                inflate.findViewById(R.id.choosePhoto).setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Intent intent_choosePhoto=new Intent(Intent.ACTION_PICK);
                        intent_choosePhoto.setType("image/*");
                        startActivityForResult(intent_choosePhoto,2);
                        dialog.dismiss();
                    }
                });
                //相机
                inflate.findViewById(R.id.takeCamera).setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        //打开相机
                        Intent intent_takePhoto=new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                        startActivityForResult(intent_takePhoto, 1);
                        dialog.dismiss();
                    }
                });
                inflate.findViewById(R.id.btn_cancel).setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        dialog.dismiss();
                    }
                });
                //将布局设置给Dialog
                dialog.setContentView(inflate);
                //获取当前Activity所在的窗体
                Window dialogWindow = dialog.getWindow();
                if(dialogWindow == null){
                    return;
                }
                //设置Dialog从窗体底部弹出
                dialogWindow.setGravity(Gravity.BOTTOM);
                //获得窗体的属性
                WindowManager.LayoutParams lp = dialogWindow.getAttributes();
                lp.y = 20;//设置Dialog距离底部的距离
                //将属性设置给窗体
                dialogWindow.setAttributes(lp);
                dialog.show();//显示对话框
            }
        });
    }

    @Override
    public void onIUpdateHeadPicSuccess(Object o) {
        if(o instanceof UpdateHeadPicBean)
        {
            UpdateHeadPicBean updateHeadPicBean = (UpdateHeadPicBean) o;
            if(o.equals("0000"))
            {
                Toast.makeText(MainActivity.this,updateHeadPicBean.getMessage(),Toast.LENGTH_SHORT).show();
            }
        }

    }

    @Override
    public void onIUpdateHeadPicFail(String errorInfo) {

    }

    @Override
    public void onPointerCaptureChanged(boolean hasCapture) {

    }
    //判断SD卡是否挂载
    public boolean hasSdcard(){
        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
            return true;
        }else{
            return false;
        }
    }
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == 1 && resultCode == MainActivity.RESULT_OK) {//相机返回的数据
            if (hasSdcard()) {
                Bitmap bitmap = data.getParcelableExtra("data");
                //将bitmap转换为uri
                Uri uri = Uri.parse(MediaStore.Images.Media.insertImage(getContentResolver(), bitmap, null, null));

                String[] proj = {MediaStore.Images.Media.DATA};

                Cursor actualimagecursor = managedQuery(uri, proj, null, null, null);

                int actual_image_column_index = actualimagecursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);

                actualimagecursor.moveToFirst();

                String img_path = actualimagecursor.getString(actual_image_column_index);

                File file = new File(img_path);
                List<File> list = new ArrayList<>();
                list.add(file);

                chuanPresenter.onIUpdateHeadPicPre(hashMap, file);

            } else {
                Toast.makeText(MainActivity.this, "未找到存储啦,无法存储照片", Toast.LENGTH_SHORT).show();
            }
        } else if (requestCode == 2 && resultCode == MainActivity.RESULT_OK) {//相册返回的数据
            //得到图片的全路径
            if (data != null) {
                Uri uri = data.getData();
                String[] proj = {MediaStore.Images.Media.DATA};
                Cursor actualimagecursor = managedQuery(uri, proj, null, null, null);
                int actual_image_column_index = actualimagecursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
                actualimagecursor.moveToFirst();
                String img_path = actualimagecursor.getString(actual_image_column_index);
                File file = new File(img_path);
                List<File> list = new ArrayList<>();
                list.add(file);
                chuanPresenter.onIUpdateHeadPicPre(hashMap, file);
            }
        }
    }
    //动态注册权限
    private void stateNetWork() {
        if(Build.VERSION.SDK_INT>= Build.VERSION_CODES.M){
            String[] mStatenetwork = new String[]{
                    //写的权限
                    Manifest.permission.WRITE_EXTERNAL_STORAGE,
                    //读的权限
                    Manifest.permission.READ_EXTERNAL_STORAGE,
                    //入网权限
                    Manifest.permission.ACCESS_NETWORK_STATE,
                    //WIFI权限
                    Manifest.permission.ACCESS_WIFI_STATE,
                    //读手机权限
                    Manifest.permission.READ_PHONE_STATE,
                    //网络权限
                    Manifest.permission.INTERNET,
                    //位置权限
                    Manifest.permission.ACCESS_COARSE_LOCATION,
                    Manifest.permission.ACCESS_FINE_LOCATION,
                    Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS,
                    //相机
                    Manifest.permission.CAMERA,
                    Manifest.permission.WRITE_APN_SETTINGS,
                    Manifest.permission.ACCESS_NETWORK_STATE,
            };
            ActivityCompat.requestPermissions(this,mStatenetwork,100);
        }
    }
}

相机相册alert弹框布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="10dp"
    android:orientation="vertical">
    <Button
        android:id="@+id/takeCamera"
        android:layout_width="match_parent"
        android:layout_height="45dp"
        android:background="#FFFFFF"
        android:gravity="center"
        android:text="相机"
        android:textColor="#999999"
        android:textSize="14sp"/>

    <View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="#9e9e9e"/>

    <Button
        android:id="@+id/choosePhoto"
        android:layout_width="match_parent"
        android:layout_height="45dp"
        android:background="#FFFFFF"
        android:gravity="center"
        android:text="相册"
        android:textColor="#999999"
        android:textSize="14sp"/>

    <Button
        android:id="@+id/btn_cancel"
        android:layout_width="match_parent"
        android:layout_height="45dp"
        android:layout_marginTop="8dp"
        android:background="#FFFFFF"
        android:gravity="center"
        android:text="取消"
        android:textColor="#999999"
        android:textSize="14sp"/>
</LinearLayout>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值