MVP进阶及OKHttp上传图片

用MVP+OKHttp实现上传图片

 

需要添加的权限

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

需要导的依赖库

implementation 'com.jakewharton:butterknife:8.8.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
implementation 'com.google.code.gson:gson:2.8.5'
implementation 'com.squareup.okhttp3:okhttp:3.12.0'

1布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    android:orientation="vertical"
    android:gravity="center_horizontal"
    tools:context=".MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:gravity="center_vertical"
        android:layout_height="wrap_content">
        <ImageView
            android:id="@+id/image_show"
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:src="@mipmap/ic_launcher"/>
        <TextView
            android:id="@+id/text_name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="用户名"/>
    </LinearLayout>
    <Button
        android:id="@+id/but_pai"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="拍照"/>
    <Button
        android:id="@+id/but_xian"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="从相册选择"/>

</LinearLayout>

2主界面

package mvp.com.example.tou;

import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import java.io.File;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import mvp.com.example.tou.bean.Result;
import mvp.com.example.tou.core.BaseCore;
import mvp.com.example.tou.presenter.PhonePresenter;
import mvp.com.example.tou.utils.StringUtil;

public class MainActivity extends AppCompatActivity implements BaseCore {

    @BindView(R.id.image_show)
    ImageView imageShow;
    @BindView(R.id.text_name)
    TextView textName;
    @BindView(R.id.but_pai)
    Button butPai;
    @BindView(R.id.but_xian)
    Button butXian;

    private static final int PHOTO_REQUEST_CAREMA = 1;// 拍照
    private static final int PHOTO_REQUEST_GALLERY = 2;// 从相册中选择
    private static final int PHOTO_REQUEST_CUT = 3;// 结果
    /* 头像名称 */
    private static final String PHOTO_FILE_NAME = "temp_photo.jpg";
    private File tempFile;
    private PhonePresenter presenter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);
        presenter = new PhonePresenter(this);
    }

    @OnClick({R.id.but_pai, R.id.but_xian})
    public void onViewClicked(View view) {
        switch (view.getId()) {
            case R.id.but_pai:
                Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
                // 判断存储卡是否可以用,可用进行存储
                if (hasSdcard()) {
                    tempFile = new File(Environment.getExternalStorageDirectory(), PHOTO_FILE_NAME);
                    // 从文件中创建uri
                    Uri uri = Uri.fromFile(tempFile);
                    intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
                }
                // 开启一个带有返回值的Activity,请求码为PHOTO_REQUEST_CAREMA
                startActivityForResult(intent, PHOTO_REQUEST_CAREMA);
                break;
            case R.id.but_xian:
                Intent intent1 = new Intent(Intent.ACTION_PICK);
                intent1.setType("image/*");
                // 开启一个带有返回值的Activity,请求码为PHOTO_REQUEST_GALLERY
                startActivityForResult(intent1, PHOTO_REQUEST_GALLERY);
                break;
        }
    }
    private boolean hasSdcard() {
        //判断SD卡手否是安装好的   media_mounted
        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            return true;
        } else {
            return false;
        }
    }
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == PHOTO_REQUEST_GALLERY) {
            // 从相册返回的数据
            if (data != null) {
                // 得到图片的全路径
                Uri uri = data.getData();
                    imageShow.setImageURI(uri);
                    String path = StringUtil.getRealPathFromUri(this,uri);
                    Log.i("dt",path);
                    //第一个参数是uid判断
                    //第二个参数是图片地址
                    presenter.read("23411",path);
            }
        } else if (requestCode == PHOTO_REQUEST_CAREMA) {
            // 从相机返回的数据
            if (hasSdcard()) {
                //(Uri.fromFile(tempFile));
                imageShow.setImageURI(Uri.fromFile(tempFile));
                String path = StringUtil.getRealPathFromUri(this,Uri.fromFile(tempFile));
                Log.i("dt",path);
                presenter.read("23411",path);
            } else {
                Toast.makeText(this, "未找到存储卡,无法存储照片!", Toast.LENGTH_SHORT).show();
            }
        }
            try {
                // 将临时文件删除
                tempFile.delete();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    @Override
    public void loadSuccess(Object data) {

    }

    @Override
    public void loadError(Result result) {

    }
}

3bean类中的泛型

package mvp.com.example.tou.bean;

public class Result<T> {

    /**
     * msg :
     * code : 0
     * data :
     */

    private String msg;
    private String code;
    private T data;

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }
}

4实现的接口

package mvp.com.example.core;

import mvp.com.example.bean.Result;

public interface BaseCore<T> {
    void loadSuccess(T data);
    void loadError(Result result);
}

5MVP....presenter 父类(相当于基类)

package mvp.com.example.tou.presenter;

import android.os.AsyncTask;

import mvp.com.example.bean.Result;
import mvp.com.example.core.BaseCore;

public abstract class BasePresenter {
    private BaseCore baseCore;

    public BasePresenter(BaseCore baseCore) {
    this.baseCore = baseCore;
    }
    public void unBaseCore(){
        baseCore = null;
    }
    public void read(String... strings){
        new MyTask().execute(strings);
    }
    class MyTask extends AsyncTask<String,Void,Result>{

        @Override
        protected Result doInBackground(String... strings) {
            Result result = onModel(strings);
            return result;
        }

        @Override
        protected void onPostExecute(Result result) {
            super.onPostExecute(result);
            if (result.getCode().equals("0")){
                baseCore.loadSuccess(result.getData());
            }else {
                baseCore.loadError(result);
            }
        }
    }
    public abstract Result onModel(String... strings);
}

6图片需要的类继承父类的preaenter

package mvp.com.example.tou.presenter;

import java.io.File;

import mvp.com.example.bean.Result;
import mvp.com.example.core.BaseCore;
import mvp.com.example.model.BaseModel;

public class PhonePresenter extends BasePresenter {
    public PhonePresenter(BaseCore baseCore) {
        super(baseCore);
    }

    @Override
    public Result onModel(String... strings) {
        File file = new File(strings[1]);
        Result result = BaseModel.PData(strings[0], file);
        return result;
    }
}

7MVP....Model层

package mvp.com.example.tou.model;

import android.util.Log;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import java.io.File;
import java.lang.reflect.Type;
import java.util.List;

import mvp.com.example.bean.Result;
import mvp.com.example.utils.HttpUtils;

public class BaseModel {
    private static final String TAG = "BaseModel======";

    public static Result PData(String name, File file) {
        String url="http://www.zhaoapi.cn/file/upload";
        //String s = Environment.getExternalStorageDirectory()+"/tou.jpg";
        HttpUtils httpUtils = HttpUtils.getHttpUtils();
        String json = httpUtils.upImage(file,url,name);
        Log.i(TAG, "LoginData: "+json);
        Gson gson = new Gson();
        Result result = gson.fromJson(json, Result.class);
        return result;
    }
}

8工具类用于okhttp上传图片

package mvp.com.example.tou.utils;

import java.io.File;
import java.io.IOException;

import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

public class HttpUtils {
    private static final String TAG = "HttpUtils---------";
    private static HttpUtils httpUtils = new HttpUtils();

    private HttpUtils() {

    }

    public static HttpUtils getHttpUtils() {
        synchronized (httpUtils) {
            if (httpUtils == null) {
                httpUtils = new HttpUtils();
            }
            return httpUtils;
        }
    }

    public String get(String url) {
        OkHttpClient okHttpClient = new OkHttpClient();

        Request request = new Request.Builder().url(url).get().build();

        try {
            Response response = okHttpClient.newCall(request).execute();
            return response.body().string();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
    public String upImage(File file,String url,String name) {
        OkHttpClient okHttpClient = new OkHttpClient();

        MultipartBody.Builder requestBody = new MultipartBody.Builder().setType(MultipartBody.FORM);
        if(file != null){
            // MediaType.parse() 里面是上传的文件类型。
            RequestBody body = RequestBody.create(MediaType.parse("image/*"), file);
            String filename = file.getName();
            // 参数分别为: 文件参数名 ,文件名称 , RequestBody
            requestBody.addFormDataPart("file", "jpg", body);
        }
        requestBody.addFormDataPart("uid",name);
        Request request = new Request.Builder().url(url).post(requestBody.build()).build();

        try {
            Response response = okHttpClient.newCall(request).execute();
            if (response.code()==200) {
                return response.body().string();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}

9用于图片转换地址的工具类

package mvp.com.example.tou.utils;

import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.provider.DocumentsContract;
import android.provider.MediaStore;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author dingtao
 * @date 2018/12/7 15:06
 * qq:1940870847
 */
public class StringUtil {

    public static boolean isPhone(String phone) {
        String regex = "^((13[0-9])|(14[5,7,9])|(15([0-3]|[5-9]))|(166)|(17[0,1,3,5,6,7,8])|(18[0-9])|(19[8|9]))\\d{8}$";
        if (phone.length() != 11) {
            return false;
        } else {
            Pattern p = Pattern.compile(regex);
            Matcher m = p.matcher(phone);
            boolean isMatch = m.matches();
            return isMatch;
        }
    }

    /**
     * 根据Uri获取图片的绝对路径
     *
     * @param context 上下文对象
     * @param uri     图片的Uri
     * @return 如果Uri对应的图片存在, 那么返回该图片的绝对路径, 否则返回null
     */
    public static String getRealPathFromUri(Context context, Uri uri) {
        int sdkVersion = Build.VERSION.SDK_INT;
        if (sdkVersion >= 19) { // api >= 19
            return getRealPathFromUriAboveApi19(context, uri);
        } else { // api < 19
            return getRealPathFromUriBelowAPI19(context, uri);
        }
    }

    /**
     * 适配api19以下(不包括api19),根据uri获取图片的绝对路径
     *
     * @param context 上下文对象
     * @param uri     图片的Uri
     * @return 如果Uri对应的图片存在, 那么返回该图片的绝对路径, 否则返回null
     */
    private static String getRealPathFromUriBelowAPI19(Context context, Uri uri) {
        return getDataColumn(context, uri, null, null);
    }

    /**
     * 适配api19及以上,根据uri获取图片的绝对路径
     *
     * @param context 上下文对象
     * @param uri     图片的Uri
     * @return 如果Uri对应的图片存在, 那么返回该图片的绝对路径, 否则返回null
     */
    private static String getRealPathFromUriAboveApi19(Context context, Uri uri) {
        String filePath = null;
        if (DocumentsContract.isDocumentUri(context, uri)) {
            // 如果是document类型的 uri, 则通过document id来进行处理
            String documentId = DocumentsContract.getDocumentId(uri);
            if (isMediaDocument(uri)) { // MediaProvider
                // 使用':'分割
                String id = documentId.split(":")[1];

                String selection = MediaStore.Images.Media._ID + "=?";
                String[] selectionArgs = {id};
                filePath = getDataColumn(context, MediaStore.Images.Media.EXTERNAL_CONTENT_URI, selection, selectionArgs);
            } else if (isDownloadsDocument(uri)) { // DownloadsProvider
                Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(documentId));
                filePath = getDataColumn(context, contentUri, null, null);
            }
        } else if ("content".equalsIgnoreCase(uri.getScheme())) {
            // 如果是 content 类型的 Uri
            filePath = getDataColumn(context, uri, null, null);
        } else if ("file".equals(uri.getScheme())) {
            // 如果是 file 类型的 Uri,直接获取图片对应的路径
            filePath = uri.getPath();
        }
        return filePath;
    }

    /**
     * 获取数据库表中的 _data 列,即返回Uri对应的文件路径
     *
     * @return
     */
    private static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) {
        String path = null;

        String[] projection = new String[]{MediaStore.Images.Media.DATA};
        Cursor cursor = null;
        try {
            cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
            if (cursor != null && cursor.moveToFirst()) {
                int columnIndex = cursor.getColumnIndexOrThrow(projection[0]);
                path = cursor.getString(columnIndex);
            }
        } catch (Exception e) {
            if (cursor != null) {
                cursor.close();
            }
        }
        return path;
    }

    /**
     * @param uri the Uri to check
     * @return Whether the Uri authority is MediaProvider
     */
    private static boolean isMediaDocument(Uri uri) {
        return "com.android.providers.media.documents".equals(uri.getAuthority());
    }

    /**
     * @param uri the Uri to check
     * @return Whether the Uri authority is DownloadsProvider
     */
    private static boolean isDownloadsDocument(Uri uri) {
        return "com.android.providers.downloads.documents".equals(uri.getAuthority());
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值