Retrofit+RxJava上傳圖片上傳圖片到後臺

在作一個商城,第一個版本使用的OkHttp3來進行網絡操做的,如今把第一個版本推倒從新作了個版本,因而就用上了正在如火如荼的Retrofit+RxJava來實現網絡操做。在上傳圖片做爲頭像時實現了一個上午也沒搞定,如今終於有時間再從新搞一下了。因而把使用OkHttp3上傳和Retrofit+RxJava上傳都總結了一下。

PS:圖片的獲取在不一樣版本上面可能會出現問題,不過這不是本文重點,主要是想展現一下上傳圖片時OkHttp3和Retrofit的參數問題。java

申請權限

<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"/>
複製代碼

獲取照片

  1. 準備請求碼和臨時變量名react

    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;
    複製代碼
  2. 開啓圖庫獲取照片android

    public void gallery() {
        Intent intent = new Intent(Intent.ACTION_PICK);
        intent.setType("image/*");
        startActivityForResult(intent, PHOTO_REQUEST_GALLERY);//攜帶請求碼
    }
    複製代碼
  3. 開啓相機獲取照片數據庫

    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);//攜帶請求碼
    }
    複製代碼
  4. 裁剪圖片bash

    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
    }複製代碼
  5. 判斷是否掛在了SD卡網絡

    private boolean hasSdcard() {
        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            return true;
        } else {
            return false;
        }
    }複製代碼
  6. 獲取的是external數據庫對應的Image文件ide

    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;
    }複製代碼
  7. 在回調中取圖片post

    @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);
}複製代碼
相關文章
相關標籤/搜索