在做一个商城,第一个版本使用的OkHttp3来进行网络操作的,现在把第一个版本推倒重新做了个版本,于是就用上了正在如火如荼的Retrofit+RxJava来实现网络操作。在上传图片作为头像时实现了一个上午也没搞定(无奈,英语差,看文档吃力啊),现在终于有时间再重新搞一下了。于是把使用OkHttp3上传和Retrofit+RxJava上传都总结了一下。废话不多说,直接贴代码,只要把代码赋值到你的项目中,包你爽到飞起。
申请权限
<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"/>
获取照片
准备请求码和临时变量名
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;
开启图库获取照片
public void gallery() { Intent intent = new Intent(Intent.ACTION_PICK); intent.setType("image/*"); startActivityForResult(intent, PHOTO_REQUEST_GALLERY);//携带请求码 }
开启相机获取照片
public void camera() { Intent intent = new Intent("android.media.action.IMAGE_CAPTURE"); if (hasSdcard()) {// 判断存储卡是否可以用,可用进行存储 tempFile = new File(Environment.getExternalStorageDirectory(), PHOTO_FILE_NAME); Uri uri = Uri.fromFile(tempFile); // 从文件中创建uri intent.putExtra(MediaStore.EXTRA_OUTPUT, uri); } startActivityForResult(intent, PHOTO_REQUEST_CAREMA);//携带请求码 }
裁剪图片
private void crop(Uri uri) { Intent intent = new Intent("com.android.camera.action.CROP"); intent.setDataAndType(uri, "image/*"); intent.putExtra("crop", "true"); // 裁剪框的比例,1:1 intent.putExtra("aspectX", 1); intent.putExtra("aspectY", 1); // 裁剪后输出图片的尺寸大小 intent.putExtra("outputX", 250); intent.putExtra("outputY", 250); intent.putExtra("outputFormat", "JPEG");// 图片格式 intent.putExtra("noFaceDetection", true);// 取消人脸识别 intent.putExtra("return-data", true); startActivityForResult(intent, PHOTO_REQUEST_CUT); // 开启一个带有返回值的Activity,请求码为PHOTO_REQUEST_CUT }
判断是否挂在了SD卡
private boolean hasSdcard() { if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { return true; } else { return false; } }
获取的是external数据库对应的Image文件
private Uri external(String external) { String myImageUrl = "content://media" + external; Uri uri = Uri.parse(myImageUrl); String[] proj = {MediaStore.Images.Media.DATA}; Cursor actualimagecursor = this.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); Uri fileUri = Uri.fromFile(file); return fileUri; }
在回调中取图片
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == PHOTO_REQUEST_GALLERY) { // 从相册返回的数据 if (data != null) {// 得到图片的全路径 Uri uri = data.getData(); crop(uri); } } else if (requestCode == PHOTO_REQUEST_CAREMA) {//从相机返回的数据 if (hasSdcard()) { crop(Uri.fromFile(tempFile)); } else { Toast.makeText(MainActivity.this, "未找到存储卡,无法存储照片!", Toast.LENGTH_LONG).show(); } } else if (requestCode == PHOTO_REQUEST_CUT) {//从剪切图片返回的数据 if (data != null) { Bitmap bitmap = data.getParcelableExtra("data"); //将bitmap转换为Uri Uri uri = Uri.parse(MediaStore.Images.Media.insertImage(getContentResolver(), bitmap, null, null)); //对非正确的Uri处理,这类Uri存在手机的external.db中,可以查询_data字段查出对应文件的uri if (uri.getPath().contains("external")) { uri = external(uri.getPath()); } //在这可以拿到裁剪后的图片Uri,然后进行你想要的操作 upLoad2Server(uri); } try { tempFile.delete();//将临时文件删除 } catch (Exception e) { e.printStackTrace(); } } super.onActivityResult(requestCode, resultCode, data); }
进行上传操作(2种方法)
1.使用OkHttp3来上传
1. 添加依赖:
compile 'com.squareup.okhttp3:okhttp:3.3.0'
2. 上传代码如下:
private void upLoad2Server(Uri uri) {
File file = null;
try {
file = new File(new URI(uri.toString()));
} catch (URISyntaxException e) {
e.printStackTrace();
}
MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM);
if (file != null) {
builder.addFormDataPart("file", file.getName(), RequestBody.create(MediaType.parse
("image*//*"), file));
}
MultipartBody requestBody = builder.build();
Request request = new Request.Builder()
.url("你的上传接口")
.post(requestBody)
.build();
OkHttpClient client = new OkHttpClient.Builder().connectTimeout(10000, TimeUnit.SECONDS).readTimeout(10000, TimeUnit.SECONDS).writeTimeout(10000, TimeUnit.SECONDS).build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, final IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
}
})
}
2.使用Retrofit+RxJava来上传
1.添加依赖
compile 'com.squareup.retrofit2:retrofit:2.1.0'
compile 'com.squareup.retrofit2:converter-gson:2.1.0'
compile 'com.squareup.retrofit2:converter-scalars:2.1.0'
compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0'
compile 'io.reactivex:rxjava:1.2.4'
compile 'io.reactivex:rxandroid:1.2.1'
2.准备上传接口
@Multipart
@POST("你的接口")
Observable<ResponseBody> upload(@Part MultipartBody.Part imgs);
public class NetApi {
public static final String BASE_URL = "你的域名";
private static NetApi mNetApi;
private static Retrofit retrofit;
private static NetService mNetService;
private NetApi() {
}
public static NetApi getInstance() {
if (null == mNetApi) {
mNetApi = new NetApi();
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build();
mNetService = retrofit.create(NetService.class);
}
return mNetApi;
}
public void upload(Subscriber<ResponseBody> subscriber, MultipartBody.Part imgs) {
mNetService.upload(imgs)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(subscriber);
}
}
3.上传方法如下:
private void upLoad2Server(Uri uri) {
File file = null;
try {
file = new File(new URI(uri.toString()));
} catch (URISyntaxException e) {
e.printStackTrace();
}
RequestBody requestBody = RequestBody.create(MediaType.parse("multipart/form-data"), file);
MultipartBody.Part body = MultipartBody.Part.createFormData("image", file.getName(), requestBody);
NetApi.getInstance().upload(new Subscriber<ResponseBody>() {
@Override
public void onCompleted() {
Log.e("MainActivity", "onCompleted");
}
@Override
public void onError(Throwable e) {
Log.e("MainActivity", "onError,"+e.getMessage());
}
@Override
public void onNext(ResponseBody responseBody) {
try {
Log.e("MainActivity", "onNext,=" + responseBody.string());
} catch (IOException e) {
e.printStackTrace();
}
}
}, body);
}