用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());
}
}