1. 程式人生 > >Android——從本地相簿上傳圖片至伺服器

Android——從本地相簿上傳圖片至伺服器

android實現本地圖片上傳至服務端,只需幾步操作即可實現,下面一起看看。

首先看下效果:
這裡寫圖片描述

主要程式碼:

package com.kevin.imageuploadclient.fragment;

import android.graphics.Bitmap;
import android.net.Uri;
import android.os.AsyncTask;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;

import
com.bumptech.glide.Glide; import com.kevin.imageuploadclient.R; import com.kevin.imageuploadclient.fragment.basic.PictureSelectFragment; import com.kevin.imageuploadclient.util.Constant; import java.io.File; import butterknife.Bind; import okhttp3.Headers; import okhttp3.MediaType; import okhttp3.MultipartBody; import
okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.RequestBody; import okhttp3.Response; /** * 圖片上傳 */ public class MainFragment extends PictureSelectFragment { /** Toolbar */ @Bind(R.id.toolbar) Toolbar toolbar; @Bind(R.id.main_frag_picture_iv) ImageView mPictureIv; public
static MainFragment newInstance() { return new MainFragment(); } @Override protected int getContentViewId() { return R.layout.fragment_main; } @Override public void initViews(View view) { initToolbar(toolbar); } @Override public void initEvents() { // 設定圖片點選監聽 mPictureIv.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { selectPicture(); } }); // 設定裁剪圖片結果監聽 setOnPictureSelectedListener(new OnPictureSelectedListener() { @Override public void onPictureSelected(Uri fileUri, Bitmap bitmap) { // mPictureIv.setImageBitmap(bitmap); String filePath = fileUri.getEncodedPath(); final String imagePath = Uri.decode(filePath); uploadImage(imagePath); } }); } /** * 上傳圖片 * @param imagePath */ private void uploadImage(String imagePath) { new NetworkTask().execute(imagePath); } /** * 訪問網路AsyncTask,訪問網路在子執行緒進行並返回主執行緒通知訪問的結果 */ class NetworkTask extends AsyncTask<String, Integer, String> { @Override protected void onPreExecute() { super.onPreExecute(); } @Override protected String doInBackground(String... params) { return doPost(params[0]); } @Override protected void onPostExecute(String result) { if(!"error".equals(result)) { Log.i(TAG, "圖片地址 " + Constant.BASE_URL + result); Glide.with(mContext) .load(Constant.BASE_URL + result) .into(mPictureIv); } } } private String doPost(String imagePath) { OkHttpClient mOkHttpClient = new OkHttpClient(); String result = "error"; MultipartBody.Builder builder = new MultipartBody.Builder(); // 這裡演示新增使用者ID // builder.addFormDataPart("userId", "20160519142605"); builder.addFormDataPart("image", imagePath, RequestBody.create(MediaType.parse("image/jpeg"), new File(imagePath))); RequestBody requestBody = builder.build(); Request.Builder reqBuilder = new Request.Builder(); Request request = reqBuilder .url(Constant.BASE_URL + "/uploadimage") .post(requestBody) .build(); Log.d(TAG, "請求地址 " + Constant.BASE_URL + "/uploadimage"); try{ Response response = mOkHttpClient.newCall(request).execute(); Log.d(TAG, "響應碼 " + response.code()); if (response.isSuccessful()) { String resultValue = response.body().string(); Log.d(TAG, "響應體 " + resultValue); return resultValue; } } catch (Exception e) { e.printStackTrace(); } return result; } }

MainFragment繼承的PictureSelectFragment是一個帶有圖片的按鈕選擇器,該類如下:
PictureSelectFragment類:

package com.kevin.imageuploadclient.fragment.basic;

import android.Manifest;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.util.Log;
import android.view.View;
import android.widget.Toast;

import com.kevin.crop.UCrop;
import com.kevin.imageuploadclient.R;
import com.kevin.imageuploadclient.activity.CropActivity;
import com.kevin.imageuploadclient.view.SelectPicturePopupWindow;

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

/**
 * 帶有圖片的選擇器按鈕
 */
public abstract class PictureSelectFragment extends BaseFragment implements SelectPicturePopupWindow.OnSelectedListener {

    private static final int GALLERY_REQUEST_CODE = 0;    // 相簿選圖示記
    private static final int CAMERA_REQUEST_CODE = 1;    // 相機拍照標記
    // 拍照臨時圖片
    private String mTempPhotoPath;
    // 剪下後圖像檔案
    private Uri mDestinationUri;

    /**
     * 選擇提示 PopupWindow
     */
    private SelectPicturePopupWindow mSelectPicturePopupWindow;
    /**
     * 圖片選擇的監聽回撥
     */
    private OnPictureSelectedListener mOnPictureSelectedListener;

    /**
     * 剪下圖片
     */
    protected void selectPicture() {
        mSelectPicturePopupWindow.showPopupWindow(mActivity);
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        mDestinationUri = Uri.fromFile(new File(activity.getCacheDir(), "cropImage.jpeg"));
        mTempPhotoPath = Environment.getExternalStorageDirectory() + File.separator + "photo.jpeg";//臨時相片
        mSelectPicturePopupWindow = new SelectPicturePopupWindow(mContext);
        mSelectPicturePopupWindow.setOnSelectedListener(this);
    }

    @Override
    public void OnSelected(View v, int position) {
        switch (position) {
            case 0:
                // "拍照"按鈕被點選了
                takePhoto();
                break;
            case 1:
                // "從相簿選擇"按鈕被點選了
                pickFromGallery();
                break;
            case 2:
                // "取消"按鈕被點選了
                mSelectPicturePopupWindow.dismissPopupWindow();
                break;
        }
    }

    /**
     * 已完成許可權請求時收到的回撥。
     */
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        switch (requestCode) {
            case REQUEST_STORAGE_READ_ACCESS_PERMISSION:
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    pickFromGallery();//從相簿選擇
                }
                break;
            case REQUEST_STORAGE_WRITE_ACCESS_PERMISSION:
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    takePhoto();//拍照
                }
                break;
            default:
                super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }

    /**
     * 調起手機拍照功能
     */
    private void takePhoto() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN // api16開始新增的許可權
                && ActivityCompat.checkSelfPermission(mActivity, Manifest.permission.WRITE_EXTERNAL_STORAGE)
                != PackageManager.PERMISSION_GRANTED) {//許可權不夠,提示
            requestPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE,
                    getString(R.string.permission_write_storage_rationale),
                    REQUEST_STORAGE_WRITE_ACCESS_PERMISSION);
        } else {//有許可權則調拍照功能
            mSelectPicturePopupWindow.dismissPopupWindow();
            Intent takeIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            //下面這句指定呼叫相機拍照後的照片儲存的路徑
            takeIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(mTempPhotoPath)));
            startActivityForResult(takeIntent, CAMERA_REQUEST_CODE);
        }
    }

    /**
     * 選擇手機相簿的照片
     */
    private void pickFromGallery() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN // api16之後需要許可權
                && ActivityCompat.checkSelfPermission(mActivity, Manifest.permission.READ_EXTERNAL_STORAGE)
                != PackageManager.PERMISSION_GRANTED) {//許可權不夠時,提示
            requestPermission(Manifest.permission.READ_EXTERNAL_STORAGE,
                    getString(R.string.permission_read_storage_rationale),
                    REQUEST_STORAGE_READ_ACCESS_PERMISSION);
        } else {//許可權足夠,開啟手機相簿
            mSelectPicturePopupWindow.dismissPopupWindow();
            Intent pickIntent = new Intent(Intent.ACTION_PICK, null);
            // 如果限制上傳到伺服器的圖片型別時可以直接寫如:"image/jpeg 、 image/png等的型別"
            pickIntent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
            startActivityForResult(pickIntent, GALLERY_REQUEST_CODE);
        }
    }

    /**
     * 回撥
     * @param requestCode
     * @param resultCode
     * @param data
     */
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode == mActivity.RESULT_OK) {
            switch (requestCode) {
                case CAMERA_REQUEST_CODE:   // 呼叫相機拍照
                    File temp = new File(mTempPhotoPath);
                    startCropActivity(Uri.fromFile(temp));//傳入臨時相片進行剪下
                    break;
                case GALLERY_REQUEST_CODE:  // 直接從相簿獲取
                    startCropActivity(data.getData());
                    break;
                case UCrop.REQUEST_CROP:    // 裁剪圖片結果
                    handleCropResult(data);
                    break;
                case UCrop.RESULT_ERROR:    // 裁剪圖片錯誤
                    handleCropError(data);
                    break;
            }
        }
        super.onActivityResult(requestCode, resultCode, data);
    }

    /**
     * 裁剪圖片方法實現
     *
     * @param uri
     */
    public void startCropActivity(Uri uri) {
        UCrop.of(uri, mDestinationUri)
                .withAspectRatio(1, 1)
                .withMaxResultSize(512, 512)//剪下尺寸
                .withTargetActivity(CropActivity.class)
                .start(mActivity, this);
    }

    /**
     * 處理剪下成功的返回值
     *
     * @param result
     */
    private void handleCropResult(Intent result) {
        deleteTempPhotoFile();
        final Uri resultUri = UCrop.getOutput(result);
        if (null != resultUri && null != mOnPictureSelectedListener) {
            Bitmap bitmap = null;
            try {
                bitmap = MediaStore.Images.Media.getBitmap(mActivity.getContentResolver(), resultUri);//獲取剪下後的圖片
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            mOnPictureSelectedListener.onPictureSelected(resultUri, bitmap);
        } else {
            Toast.makeText(mContext, "無法剪下選擇圖片", Toast.LENGTH_SHORT).show();
        }
    }

    /**
     * 處理剪下失敗的返回值
     *
     * @param result
     */
    private void handleCropError(Intent result) {
        deleteTempPhotoFile();
        final Throwable cropError = UCrop.getError(result);
        if (cropError != null) {
            Log.e(TAG, "handleCropError: ", cropError);
            Toast.makeText(mContext, cropError.getMessage(), Toast.LENGTH_LONG).show();
        } else {
            Toast.makeText(mContext, "無法剪下選擇圖片", Toast.LENGTH_SHORT).show();
        }
    }

    /**
     * 刪除拍照臨時檔案
     */
    private void deleteTempPhotoFile() {
        File tempFile = new File(mTempPhotoPath);
        if (tempFile.exists() && tempFile.isFile()) {
            tempFile.delete();
        }
    }

    /**
     * 設定圖片選擇的回撥監聽
     *
     * @param l
     */
    public void setOnPictureSelectedListener(OnPictureSelectedListener l) {
        this.mOnPictureSelectedListener = l;
    }

    /**
     * 圖片選擇的回撥介面
     */
    public interface OnPictureSelectedListener {
        /**
         * 圖片選擇的監聽回撥
         *
         * @param fileUri
         * @param bitmap
         */
        void onPictureSelected(Uri fileUri, Bitmap bitmap);
    }

}

BaseFragment是繼承Fragment類,在BaseFragment中做了請求許可權,還有幾個抽象方法:
BaseFragment類:

package com.kevin.imageuploadclient.fragment.basic;

import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.kevin.imageuploadclient.R;

import butterknife.ButterKnife;
public abstract class BaseFragment extends Fragment {

    /** 類標籤 */
    protected static String TAG = "";
    /** 上下文 */
    protected Context mContext  = null;
    /** 依附的Activity */
    protected Activity mActivity= null;

    private AlertDialog mAlertDialog;
    protected static final int REQUEST_STORAGE_READ_ACCESS_PERMISSION = 101;
    protected static final int REQUEST_STORAGE_WRITE_ACCESS_PERMISSION = 102;

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        TAG = this.getClass().getSimpleName();
        mContext  = activity;
        mActivity = activity;
//      LogUtils.i(getFragmentName() + " onAttach()");
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
//      LogUtils.i(getFragmentName() + " onCreate()");
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
//      LogUtils.i(getFragmentName() + " onCreateView()");
        if (getContentViewId() != 0) {
            return inflater.inflate(getContentViewId(), null);
        } else {
            return super.onCreateView(inflater, container, savedInstanceState);
        }
    }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
//      LogUtils.i(getFragmentName() + " onViewCreated()");
        ButterKnife.bind(this, view);
        init();
        initViews(view);
        initData();
        initEvents();
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
//      LogUtils.i(getFragmentName() + " onActivityCreated()");
    }

    @Override
    public void onStart() {
        super.onStart();
//      LogUtils.i(getFragmentName() + " onStart()");
    }

    @Override
    public void onResume() {
        super.onResume();
//      LogUtils.i(getFragmentName() + " onResume()");
    }

    @Override
    public void onPause() {
        super.onPause();
//      LogUtils.i(getFragmentName() + " onPause()");
    }

    @Override
    public void onStop() {
        super.onStop();
//      LogUtils.i(getFragmentName() + " onStop()");
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
//      LogUtils.i(getFragmentName() + " onDestroyView()");
        ButterKnife.unbind(this);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
//      LogUtils.i(getFragmentName() + " onDestroy()");
    }

    @Override
    public void onDetach() {
        super.onDetach();
//      LogUtils.i(getFragmentName() + " onDetach()");
    }

    /**
     * 使用Toolbar代替ActionBar
     *
     * @return void
     */
    protected void initToolbar(Toolbar toolbar) {
        ((AppCompatActivity)mActivity).setSupportActionBar(toolbar);
    }

    /**
     * 使用Toolbar代替ActionBar
     *
     * @return void
     */
    protected void initToolbar(Toolbar toolbar, String title) {
        toolbar.setTitle(title);
        initToolbar(toolbar);
    }

    /**
     * 請求許可權
     *
     * 如果許可權被拒絕過,則提示使用者需要許可權
     */
    protected void requestPermission(final String permission, String rationale, final int requestCode) {
        if (shouldShowRequestPermissionRationale(permission)) {
            showAlertDialog(getString(R.string.permission_title_rationale), rationale,
                    new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            requestPermissions(new String[]{permission}, requestCode);
                        }
                    }, getString(R.string.label_ok), null, getString(R.string.label_cancel));
        } else {
            requestPermissions(new String[]{permission}, requestCode);
        }
    }

    /**
     * 顯示指定標題和資訊的對話方塊
     *
     * @param title                         - 標題
     * @param message                       - 資訊
     * @param onPositiveButtonClickListener - 肯定按鈕監聽
     * @param positiveText                  - 肯定按鈕資訊
     * @param onNegativeButtonClickListener - 否定按鈕監聽
     * @param negativeText                  - 否定按鈕資訊
     */
    protected void showAlertDialog(@Nullable String title, @Nullable String message,
                                   @Nullable DialogInterface.OnClickListener onPositiveButtonClickListener,
                                   @NonNull String positiveText,
                                   @Nullable DialogInterface.OnClickListener onNegativeButtonClickListener,
                                   @NonNull String negativeText) {
        AlertDialog.Builder builder = new AlertDialog.Builder(mActivity);
        builder.setTitle(title);
        builder.setMessage(message);
        builder.setPositiveButton(positiveText, onPositiveButtonClickListener);
        builder.setNegativeButton(negativeText, onNegativeButtonClickListener);
        mAlertDialog = builder.show();
    }

    /**
     * 獲取當前Fragment的名稱
     * @return
     */
    public String getFragmentName(){
        return TAG;
    }

    /** 初始化方法 */
    public void init() {}
    /** 設定佈局 */
    protected abstract int getContentViewId();
    /** 初始化View的抽象方法 */
    public abstract void initViews(View view);
    /** 初始化資料 */
    protected void initData() {}
    /** 初始化事件的抽象方法 */
    public abstract void initEvents();

}

同樣,圖片剪下一樣是繼承了自己寫的,前面圖片剪下的方法中的CropActivity類:

package com.kevin.imageuploadclient.activity;

import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.net.Uri;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;

import com.kevin.crop.UCrop;
import com.kevin.crop.util.BitmapLoadUtils;
import com.kevin.crop.view.CropImageView;
import com.kevin.crop.view.GestureCropImageView;
import com.kevin.crop.view.OverlayView;
import com.kevin.crop.view.TransformImageView;
import com.kevin.crop.view.UCropView;
import com.kevin.imageuploadclient.R;
import com.kevin.imageuploadclient.activity.basic.BaseActivity;

import java.io.OutputStream;

import butterknife.Bind;
public class CropActivity extends BaseActivity {

    private static final String TAG = "CropActivity";

    @Bind(R.id.toolbar)
    Toolbar mToolBar;
    @Bind(R.id.weixin_act_ucrop)
    UCropView mUCropView;
    GestureCropImageView mGestureCropImageView;
    OverlayView mOverlayView;

    @Bind(R.id.crop_act_save_fab)
    FloatingActionButton mSaveFab;

    private Uri mOutputUri;

    @Override
    protected void initContentView() {
        setContentView(R.layout.activity_crop);
    }

    @Override
    protected void initViews() {
        initToolBar();

        mGestureCropImageView = mUCropView.getCropImageView();
        mOverlayView = mUCropView.getOverlayView();

        // 設定允許縮放
        mGestureCropImageView.setScaleEnabled(true);
        // 設定禁止旋轉
        mGestureCropImageView.setRotateEnabled(false);
        // 設定剪下後的最大寬度
//        mGestureCropImageView.setMaxResultImageSizeX(300);
        // 設定剪下後的最大高度
//        mGestureCropImageView.setMaxResultImageSizeY(300);

        // 設定外部陰影顏色
        mOverlayView.setDimmedColor(Color.parseColor("#AA000000"));
        // 設定周圍陰影是否為橢圓(如果false則為矩形)
        mOverlayView.setOvalDimmedLayer(false);
        // 設定顯示裁剪邊框
        mOverlayView.setShowCropFrame(true);
        // 設定不顯示裁剪網格
        mOverlayView.setShowCropGrid(false);

        final Intent intent = getIntent();
        setImageData(intent);
    }

    /**
     * 初始化ToolBar
     */
    private void initToolBar() {
        mToolBar.setTitle("裁剪圖片");
        setSupportActionBar(mToolBar);
        mToolBar.setNavigationIcon(R.drawable.abc_ic_ab_back_mtrl_am_alpha);
    }

    @Override
    protected void initEvents() {
        mGestureCropImageView.setTransformImageListener(mImageListener);
        mSaveFab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                cropAndSaveImage();
            }
        });
    }

    private void setImageData(Intent intent) {
        Uri inputUri = intent.getParcelableExtra(UCrop.EXTRA_INPUT_URI);
        mOutputUri = intent.getParcelableExtra(UCrop.EXTRA_OUTPUT_URI);

        if (inputUri != null && mOutputUri != null) {
            try {
                mGestureCropImageView.setImageUri(inputUri);
            } catch (Exception e) {
                setResultException(e);
                finish();
            }
        } else {
            setResultException(new NullPointerException("Both input and output Uri must be specified"));
            finish();
        }

        // 設定裁剪寬高比
        if (intent.getBooleanExtra(UCrop.EXTRA_ASPECT_RATIO_SET, false)) {
            float aspectRatioX = intent.getFloatExtra(UCrop.EXTRA_ASPECT_RATIO_X, 0);
            float aspectRatioY = intent.getFloatExtra(UCrop.EXTRA_ASPECT_RATIO_Y, 0);

            if (aspectRatioX > 0 && aspectRatioY > 0) {
                mGestureCropImageView.setTargetAspectRatio(aspectRatioX / aspectRatioY);
            } else {
                mGestureCropImageView.setTargetAspectRatio(CropImageView.SOURCE_IMAGE_ASPECT_RATIO);
            }
        }

        // 設定裁剪的最大寬高
        if (intent.getBooleanExtra(UCrop.EXTRA_MAX_SIZE_SET, false)) {
            int maxSizeX = intent.getIntExtra(UCrop.EXTRA_MAX_SIZE_X, 0);
            int maxSizeY = intent.getIntExtra(UCrop.EXTRA_MAX_SIZE_Y, 0);

            if (maxSizeX > 0 && maxSizeY > 0) {
                mGestureCropImageView.setMaxResultImageSizeX(maxSizeX);
                mGestureCropImageView.setMaxResultImageSizeY(maxSizeY);
            } else {
                Log.w(TAG, "EXTRA_MAX_SIZE_X and EXTRA_MAX_SIZE_Y must be greater than 0");
            }
        }
    }

    private void cropAndSaveImage() {
        OutputStream outputStream = null;
        try {
            final Bitmap croppedBitmap = mGestureCropImageView.cropImage();
            if (croppedBitmap != null) {
                outputStream = getContentResolver().openOutputStream(mOutputUri);
                croppedBitmap.compress(Bitmap.CompressFormat.JPEG, 85, outputStream);
                croppedBitmap.recycle();

                setResultUri(mOutputUri, mGestureCropImageView.getTargetAspectRatio());
                finish();
            } else {
                setResultException(new NullPointerException("CropImageView.cropImage() returned null."));
            }
        } catch (Exception e) {
            setResultException(e);
            finish();
        } finally {
            BitmapLoadUtils.close(outputStream);
        }
    }

    private TransformImageView.TransformImageListener mImageListener = new TransformImageView.TransformImageListener() {
        @Override
        public void onRotate(float currentAngle) {
//            setAngleText(currentAngle);
        }

        @Override
        public void onScale(float currentScale) {
//            setScaleText(currentScale);
        }

        @Override
        public void onLoadComplete() {
            Animation fadeInAnimation = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.crop_fade_in);
            fadeInAnimation.setAnimationListener(new Animation.AnimationListener() {
                @Override
                public void onAnimationStart(Animation animation) {
                    mUCropView.setVisibility(View.VISIBLE);
                    mGestureCropImageView.setImageToWrapCropBounds();
                }

                @Override
                public void onAnimationEnd(Animation animation) {

                }

                @Override
                public void onAnimationRepeat(Animation animation) {
                }
            });
            mUCropView.startAnimation(fadeInAnimation);
        }

        @Override
        public void onLoadFailure(Exception e) {
            setResultException(e);
            finish();
        }

    };

    private void setResultUri(Uri uri, float resultAspectRatio) {
        setResult(RESULT_OK, new Intent()
                .putExtra(UCrop.EXTRA_OUTPUT_URI, uri)
                .putExtra(UCrop.EXTRA_OUTPUT_CROP_ASPECT_RATIO, resultAspectRatio));
    }

    private void setResultException(Throwable throwable) {
        setResult(UCrop.RESULT_ERROR, new Intent().putExtra(UCrop.EXTRA_ERROR, throwable));
    }
}

BaseActivity類:

package com.kevin.imageuploadclient.activity.basic;

import android.content.Context;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.ViewConfiguration;

import com.kevin.imageuploadclient.KevinApplication;

import java.lang.reflect.Field;

import butterknife.ButterKnife;

public abstract class BaseActivity extends ActionBarActivity {

    protected Context mContext = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        mContext = this;
        KevinApplication.getInstance().mActivityStack.addActivity(this);
        setOverflowShowingAlways();
        super.onCreate(savedInstanceState);

        initContentView();
        ButterKnife.bind(this);
        init();
        initViews();
        initEvents();
    }

    /**
     * 設定總是顯示溢位選單
     */
    private void setOverflowShowingAlways() {
        try {
            ViewConfiguration config = ViewConfiguration.get(this);
            Field menuKeyField = ViewConfiguration.class.getDeclaredField("sHasPermanentMenuKey");
            menuKeyField.setAccessible(true);
            menuKeyField.setBoolean(config, false);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    protected void onStart() {
        super.onStart();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        ButterKnife.unbind(this);
    }

    public void finish() {
        super.finish();
        KevinApplication.getInstance().mActivityStack.removeActivity(this);
    }

    /**
     * 初始化佈局
     */
    protected abstract void initContentView();

    /**
     * 初始化
     */
    protected void init() {
    }

    /**
     * 初始化View
     */
    protected abstract void initViews();

    /**
     * 初始化事件
     */
    protected abstract void initEvents();
}

大家需要的話下面是下載地址,提醒一點,如果你想在客戶端跑起來上傳圖片,必須要啟動服務端,服務端的文章在這裡,在上一篇的最下面一樣附上了下載地址,只需要在客戶端修改伺服器地址就可以了。

相關推薦

Android——本地相簿圖片伺服器

android實現本地圖片上傳至服務端,只需幾步操作即可實現,下面一起看看。 首先看下效果: 主要程式碼: package com.kevin.imageuploadclient.fragment; import android.graphics

微信小程式如何圖片伺服器(node.js例項分享)

一、前臺處理 (1)首先在wxml中為按鈕繫結上傳圖片事件 <button bindtap="upImgClick">上傳圖片</button> <image src='{{imgUrl}}'></image>

用postman 圖片伺服器

from flask import Flask,request app = Flask(__name__) @app.route('/',methods=['POST','GET']) def index(): name = request.form.get("name") age =

呼叫系統相簿圖片伺服器--OPPO等部分手機出現短暫的顯示桌面問題

主要原因是主體樣式設定的問題:這裡把appTheme設定一個style即可:         <item name="android:windowBackground">@color/white</item>         <!--下面這個屬

記錄:php圖片伺服器 並返回顯示圖片地址

前端上傳圖片主要程式碼:upload_test.html<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"&g

在fragment中實現Android圖片本地JavaWeb服務器

prop prefix adt ilo err 1.10 response try 轉換成 服務器端: 需要一個接受文件的servlet,以及導入兩個包:commons-fileupload-1.3.1.jar 和 commons-io-2.4.jar import ja

[Android] WebView中拍照或相簿圖片

  WebView 上傳圖片, 想必很多人都碰到過這樣的場景. 而且 WebView 在4.4前後的區別非常大, 比如對URL跳轉的格式, 對JS的注入宣告等等, 4.4以後的WebView 已經是chromium核心, 有多強大就無需我贅述. 說這些, 其實也

圖片數據庫及數據庫中讀取圖片顯示頁面

for循環 common 基於 serial 文件創建 每一個 super lis size 1.基於最簡單的servlet+jsp+jdbc實現 2.實驗環境:myeclipse以及tomcat 8.5 3.所需jar包:    4.數據庫:   數據庫用的是mysql

使用“rz -be”命令檔案伺服器;使用“sz 檔名”伺服器下載檔案到本地

我們知道在與linux 做檔案交換的時候,經常會使用到windows 檔案上傳到linux 或者linux 檔案下載到windows之類的情況,其中大家使用比較常用的就是 Xftp,sftp,FileZilla等,那麼今天就介紹另外一種方式上傳與下載檔案rz/sz 測試環境: CentOs

java 圖片本地 並讀取圖片在網頁中顯示

java 上傳圖片至本地 並讀取圖片在網頁中顯示 程式碼+圖片如下所示 一、程式碼 @Controller public class ImageController { private static Logger logger = LoggerFactory.getLogge

WebView中拍照或相簿圖片

WebView 上傳圖片, 想必很多人都碰到過這樣的場景. 而且 WebView 在4.4前後的區別非常大, 比如對URL跳轉的格式, 對JS的注入宣告等等, 4.4以後的WebView 已經是chromium核心, 有多強大就無需我贅述. 說這些, 其實也是

Android H5和App互動以及開啟相簿圖片並顯示

一、H5連結開啟App 點選瀏覽器中的URL,如何啟動App呢? 1、HTML連結處理 首先做成HTML的內容,url格式如下: <a href="[scheme]://[host]/[path]?[query]">啟動應用程式</a> 說明:

Android圖片java伺服器

這幾天有做到一個小的案例,手機拍照、相簿照片上傳到伺服器。客戶端和伺服器的程式碼都貼出來: 客戶端 AndroidManifest.xml新增以下許可權 <uses-permission android:name="android.permiss

微信小程式 圖片阿里雲OSS(支援多圖片

我們先講下為什麼要把圖片檔案上傳到雲伺服器呢, 有什麼好處呢? 1、能減輕我們自己伺服器的頻寬 如果一個程式裡有多處地方用到使用者上傳圖片等功能的話,建議還是放到阿里雲或者千牛雲等其他平臺上來儲存我們的圖片,可以給公司的伺服器減少很多壓力,磁碟儲存也就不會太大 2、提升使用者體驗感

winform端圖片flask伺服器

winform端程式碼: public static string PostImageData(string url, IDictionary<string, string> parameters, int timeout, string userAgent, CookieColle

使用jsJdk非同步圖片OSS伺服器

阿里雲官方文件中給的基本都是同步上傳檔案的DEMO,可能是非同步的比較簡單,但是由於自己JS基礎還不夠牢固,在學習使用的時候也很鬧心,因為老是看著看著就看到非同步的那邊去了。將自己寫好的的一個DEMO放於部落格中,萬一能夠幫助到任何一個和我一樣的朋友也是好的。 <!DOCTYPE html&

本地初次程式碼gitlab

以前做過的專案中用過Git和GitHub,這次用的是GitLab,以下是網路上對三者區別的描述,我覺得很形象:     Git是一種版本控制系統(Version Control System,VCS),是一種工具。   &nbs

圖片fastdfs分散式檔案系統並回顯

事件,當我們瀏覽完圖片選中一張時,觸發onchange事件將圖片上傳到伺服器並回顯、 1 <img width="100" height="100" id="allUrl" src="${brand.imgUrl }"/> 2 <input type="hidden" name

Android圖片伺服器並顯示(後臺用Java處理)

Android上傳圖片(Android Studio) Fragment介面: private String img_src; /** * 從相簿選取圖片 */ public void selectImg() { Intent intent = new

JAVA 圖片阿里OSS儲存庫

1.建立一個工具類OSSUtil.java,程式碼如下: package com.qyrj.util; import com.aliyun.oss.OSSClient; import com.aliyun.oss.model.PutObjectRequest; import java.io.By