com.snappy.CameraCropActivity.java Source code

Java tutorial

Introduction

Here is the source code for com.snappy.CameraCropActivity.java

Source

/*
 * The MIT License (MIT)
 * 
 * Copyright  2013 Clover Studio Ltd. All rights reserved.
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

package com.snappy;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.concurrent.ExecutionException;

import org.json.JSONException;

import android.annotation.SuppressLint;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.graphics.drawable.Drawable;
import android.media.ExifInterface;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.provider.MediaStore;
import android.text.format.DateFormat;
import android.util.FloatMath;
import android.view.Display;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
import android.widget.RelativeLayout;
import android.widget.Toast;

import com.snappy.couchdb.Command;
import com.snappy.couchdb.CouchDB;
import com.snappy.couchdb.ResultListener;
import com.snappy.couchdb.SpikaAsyncTask;
import com.snappy.couchdb.SpikaException;
import com.snappy.extendables.SpikaActivity;
import com.snappy.management.BitmapManagement;
import com.snappy.messageshandling.SendMessageAsync;
import com.snappy.utils.Const;
import com.snappy.utils.FileUtils;
import com.snappy.utils.Logger;
import com.snappy.utils.Utils;
import com.snappy.view.CroppedImageView;

/**
 * CameraCropActivity
 * 
 * Creates cropped image from a gallery photo using a square frame.
 */

public class CameraCropActivity extends SpikaActivity implements OnTouchListener {

    // These matrices will be used to move and zoom image
    private Matrix matrix = new Matrix();
    private Matrix savedMatrix = new Matrix();
    private Matrix translateMatrix = new Matrix();

    // We can be in one of these 3 states
    private static final int NONE = 0;
    private static final int DRAG = 1;
    private static final int ZOOM = 2;
    private int mode = NONE;

    // Remember some things for zooming
    private PointF start = new PointF();
    private PointF mid = new PointF();
    private float oldDist = 1f;

    private CroppedImageView mImageView;
    private Bitmap mBitmap;

    public int crop_container_size;

    private float mAspect;

    private float start_x, start_y;

    // Gallery type marker
    private static final int GALLERY = 1;
    // Camera type marker
    private static final int CAMERA = 2;
    // Uri for captured image so we can get image path
    private String _path;

    public static boolean return_flag;

    private boolean mIsCamera;
    private boolean mTrio;
    private boolean mPlanner;
    private String mGroupId = "";

    //   private ProgressDialog mProgressDialog;

    private boolean mForProfile;
    private boolean mForGroup;
    private boolean mForGroupUpdate;

    private String mFilePath;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_camera_crop);

        getImageIntents();
        mImageView = (CroppedImageView) findViewById(R.id.ivCameraCropPhoto);
        mImageView.setDrawingCacheEnabled(true);

        return_flag = false;

        Button btnBack = (Button) findViewById(R.id.btnBack);
        btnBack.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                finish();
            }
        });

        // Cancel button
        findViewById(R.id.btnCameraCancel).setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                finish();
                if (getIntent().getStringExtra("type").equals("gallery")) {
                    Intent intent = new Intent(CameraCropActivity.this, CameraCropActivity.class);
                    intent.putExtra("type", "gallery");
                    startActivity(intent);
                } else {
                    Intent intent = new Intent(CameraCropActivity.this, CameraCropActivity.class);
                    intent.putExtra("type", "camera");
                    startActivity(intent);
                }
            }
        });

        // Next button
        findViewById(R.id.btnCameraOk).setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                final Bitmap resizedBitmap = getBitmapFromView(mImageView);
                ByteArrayOutputStream bs = new ByteArrayOutputStream();
                resizedBitmap.compress(Bitmap.CompressFormat.JPEG, 100, bs);

                //                  new AsyncTask<Void, Void, Boolean>() {
                //                  
                //                     @Override
                //                     protected Boolean doInBackground(Void... params) {
                //                        return saveBitmapToFile(resizedBitmap, mFilePath);
                //                     }
                //                     
                //                     @Override
                //                     protected void onPostExecute(Boolean result) {
                //                        if (result == true) {
                //                           if (mForProfile == true) {
                //                              MyProfileActivity.gProfileImage = getBitmapFromView(mImageView);
                //                              MyProfileActivity.gProfileImagePath = mFilePath;
                //                              finish();
                //                           }else if (mForGroup == true) {
                //                              CreateGroupActivity.gGroupImage = getBitmapFromView(mImageView);
                //                              CreateGroupActivity.gGroupImagePath = mFilePath;
                //                              finish();
                //                           }else if (mForGroupUpdate == true) {
                //                              GroupProfileActivity.gGroupImage = getBitmapFromView(mImageView);
                //                              GroupProfileActivity.gGroupImagePath = mFilePath;
                //                              finish();
                //                           }else {
                //                              fileUploadAsync(mFilePath);
                //                           }}else {
                //                              Toast.makeText(CameraCropActivity.this,   "Failed to send photo", Toast.LENGTH_LONG).show();
                //                           }
                //                        }
                //                     
                //                  }.execute();

                if (saveBitmapToFile(resizedBitmap, mFilePath) == true) {

                    if (mForProfile == true) {
                        MyProfileActivity.gProfileImage = getBitmapFromView(mImageView);
                        MyProfileActivity.gProfileImagePath = mFilePath;
                        finish();
                    } else if (mForGroup == true) {
                        CreateGroupActivity.gGroupImage = getBitmapFromView(mImageView);
                        CreateGroupActivity.gGroupImagePath = mFilePath;
                        finish();
                    } else if (mForGroupUpdate == true) {
                        GroupProfileActivity.gGroupImage = getBitmapFromView(mImageView);
                        GroupProfileActivity.gGroupImagePath = mFilePath;
                        finish();
                    } else {
                        fileUploadAsync(mFilePath);
                        //                        new FileUploadAsync(CameraCropActivity.this)
                        //                              .execute(mFilePath);
                        // new SendMessageAsync(getApplicationContext(),
                        // SendMessageAsync.TYPE_PHOTO)
                        // .execute(resizedBitmap);
                    }

                } else {
                    Toast.makeText(CameraCropActivity.this, "Failed to send photo", Toast.LENGTH_LONG).show();
                }

            }
        });
    }

    private void getImageIntents() {
        /*
         * if (getIntent().hasExtra("trio")) { _trio = true; _groupId =
         * getIntent().getStringExtra("groupId"); _planner =
         * getIntent().getBooleanExtra("planner", false); } else { _trio =
         * false; _planner = false; _groupId = ""; }
         */
        if (getIntent().getStringExtra("type").equals("gallery")) {

            //this is used to solve the selected path for android 19, kitkat o superior
            if (Build.VERSION.SDK_INT < 19) {
                Intent intent = new Intent();
                intent.setType("image/*");
                intent.setAction(Intent.ACTION_GET_CONTENT);
                this.startActivityForResult(intent, GALLERY);
            } else {
                Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
                intent.addCategory(Intent.CATEGORY_OPENABLE);
                intent.setType("image/*");
                this.startActivityForResult(intent, GALLERY);
            }

            mIsCamera = false;

        } else {
            try {
                startCamera();
                mIsCamera = true;
            } catch (UnsupportedOperationException ex) {
                ex.printStackTrace();
                Toast.makeText(getBaseContext(), "UnsupportedOperationException", Toast.LENGTH_SHORT).show();
            }
        }
        if (getIntent().getBooleanExtra("profile", false) == true) {
            mForProfile = true;
        } else {
            mForProfile = false;
        }
        if (getIntent().getBooleanExtra("createGroup", false) == true) {
            mForGroup = true;
        } else {
            mForGroup = false;
        }
        if (getIntent().getBooleanExtra("groupUpdate", false) == true) {
            mForGroupUpdate = true;
        } else {
            mForGroupUpdate = false;
        }
    }

    public void startCamera() {
        // Check if camera exists
        if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
            Toast.makeText(this, R.string.no_camera, Toast.LENGTH_LONG).show();
            finish();
        } else {
            try {
                long date = System.currentTimeMillis();
                String filename = DateFormat.format("yyyy-MM-dd_kk.mm.ss", date).toString() + ".jpg";
                _path = this.getExternalCacheDir() + "/" + filename;
                File file = new File(_path);
                //            File file = new File(getFileDir(getBaseContext()), filename);
                Uri outputFileUri = Uri.fromFile(file);
                Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
                startActivityForResult(intent, CAMERA);
            } catch (Exception ex) {
                Toast.makeText(this, R.string.no_camera, Toast.LENGTH_LONG).show();
                finish();
            }

        }
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);

        String pManufacturer = android.os.Build.MANUFACTURER;
        String pModel = android.os.Build.MODEL;

        if ("GT-I9300".equals(pModel) && "samsung".equals(pManufacturer)) {

            RelativeLayout main = (RelativeLayout) findViewById(R.id.relativeLayout_main);
            main.invalidate();

            setContentView(R.layout.activity_camera_crop);

            mImageView = (CroppedImageView) findViewById(R.id.ivCameraCropPhoto);
            mImageView.setDrawingCacheEnabled(true);

            scaleView();

            // Cancel button
            findViewById(R.id.btnCameraCancel).setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {

                    finish();
                    if (getIntent().getStringExtra("type").equals("gallery")) {
                        Intent intent = new Intent(CameraCropActivity.this, CameraCropActivity.class);
                        intent.putExtra("type", "gallery");
                        startActivity(intent);
                    } else {
                        Intent intent = new Intent(CameraCropActivity.this, CameraCropActivity.class);
                        intent.putExtra("type", "camera");
                        startActivity(intent);
                    }
                }
            });

            // Next button
            findViewById(R.id.btnCameraOk).setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {
                    Bitmap resizedBitmap = getBitmapFromView(mImageView);

                    ByteArrayOutputStream bs = new ByteArrayOutputStream();
                    resizedBitmap.compress(Bitmap.CompressFormat.JPEG, 100, bs);

                    if (saveBitmapToFile(resizedBitmap, mFilePath) == true) {

                        if (mForProfile == true) {
                            MyProfileActivity.gProfileImage = getBitmapFromView(mImageView);
                            MyProfileActivity.gProfileImagePath = mFilePath;
                        } else if (mForGroup == true) {
                            CreateGroupActivity.gGroupImage = getBitmapFromView(mImageView);
                            CreateGroupActivity.gGroupImagePath = mFilePath;
                        } else if (mForGroupUpdate == true) {
                            GroupProfileActivity.gGroupImage = getBitmapFromView(mImageView);
                            GroupProfileActivity.gGroupImagePath = mFilePath;
                        } else {
                            fileUploadAsync(mFilePath);

                            //                           new FileUploadAsync(CameraCropActivity.this)
                            //                                 .execute(mFilePath);
                            // new
                            // SendMessageAsync(getApplicationContext(),
                            // SendMessageAsync.TYPE_PHOTO)
                            // .execute(resizedBitmap);
                        }
                    } else {
                        Toast.makeText(CameraCropActivity.this, R.string.cameracrop_imagesend_failed,
                                Toast.LENGTH_LONG).show();
                    }

                }
            });

            File file = new File(_path);
            boolean exists = file.exists();
            if (exists)
                onPhotoTaken(_path);
            else
                Toast.makeText(getBaseContext(), R.string.cameracrop_image_fatalerror, Toast.LENGTH_SHORT).show();
        }

    }

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        // TODO Auto-generated method stub
        super.onWindowFocusChanged(hasFocus);
        if (hasFocus) {
            scaleView();
        }
    }

    public void scaleView() {
        // instantiate the views
        View top_view = findViewById(R.id.topView);
        View bottom_view = findViewById(R.id.bottomView);
        LinearLayout footer = (LinearLayout) findViewById(R.id.llFooter);
        LinearLayout crop_frame = (LinearLayout) findViewById(R.id.llCropFrame);
        Display display = getWindowManager().getDefaultDisplay();
        int width = display.getWidth();
        int height = display.getHeight();

        // 90% of width
        crop_container_size = (int) ((float) width * (1f - (10f / 100f)));

        // 10% margins
        float margin = ((float) width * (1f - (90f / 100f)));

        // Parameters for white crop border
        LinearLayout.LayoutParams par = new LinearLayout.LayoutParams(crop_container_size, crop_container_size);
        par.gravity = Gravity.CENTER_HORIZONTAL | Gravity.CENTER_VERTICAL;
        par.setMargins((int) (margin / 2f), 0, (int) (margin / 2f), 0);
        crop_frame.setLayoutParams(par);

        // Margins for other transparent views
        float top_view_height = ((float) (height - crop_container_size - footer.getHeight())) / (float) 2;
        top_view.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, (int) top_view_height));
        bottom_view
                .setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, (int) top_view_height));

        // Image container
        RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(crop_container_size,
                crop_container_size);
        params.setMargins((int) (margin / 2f), (int) top_view_height, (int) (margin / 2f), 0);
        mImageView.setLayoutParams(params);
        mImageView.setImageBitmap(mBitmap);
        mImageView.setMaxZoom(4f);
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        ImageView view = (ImageView) v;
        switch (event.getAction() & MotionEvent.ACTION_MASK) {
        case MotionEvent.ACTION_DOWN:
            savedMatrix.set(matrix);
            start.set(event.getX(), event.getY());
            mode = DRAG;
            break;
        case MotionEvent.ACTION_POINTER_DOWN:
            oldDist = spacing(event);
            if (oldDist > 10f) {
                savedMatrix.set(matrix);
                midPoint(mid, event);
                mode = ZOOM;
            }
            break;
        case MotionEvent.ACTION_UP:
        case MotionEvent.ACTION_POINTER_UP:
            mode = NONE;
            break;
        case MotionEvent.ACTION_MOVE:
            if (mode == DRAG) {
                // ...
                matrix.set(savedMatrix);
                matrix.postTranslate(event.getX() - start.x, event.getY() - start.y);
                start_x = event.getX() - start.x;
                start_y = event.getY() - start.y;
            } else if (mode == ZOOM) {
                float newDist = spacing(event);
                if (newDist > 10f) {
                    matrix.set(savedMatrix);
                    float scale = newDist / oldDist;
                    mAspect = scale;
                    matrix.postScale(scale, scale, mid.x, mid.y);
                }
            }
            break;
        }

        view.setImageMatrix(matrix);
        view.invalidate();
        return true;
    }

    /**
     * Get the image from container - it is already cropped and zoomed If the
     * image is smaller than container it will be black color set aside
     * */
    private Bitmap getBitmapFromView(View view) {
        Bitmap returnedBitmap = Bitmap.createBitmap(crop_container_size, crop_container_size,
                Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(returnedBitmap);
        Drawable bgDrawable = view.getBackground();
        if (bgDrawable != null)
            bgDrawable.draw(canvas);
        else
            canvas.drawColor(Color.BLACK);
        view.draw(canvas);
        return returnedBitmap;
    }

    /** Determine the space between the first two fingers */
    @SuppressLint("FloatMath")
    private float spacing(MotionEvent event) {
        float x = event.getX(0) - event.getX(1);
        float y = event.getY(0) - event.getY(1);
        return FloatMath.sqrt(x * x + y * y);
    }

    /** Calculate the mid point of the first two fingers */
    private void midPoint(PointF point, MotionEvent event) {
        float x = event.getX(0) + event.getX(1);
        float y = event.getY(0) + event.getY(1);
        point.set(x / 2, y / 2);
    }

    private void _scaleBitmap() {
        int image_width = this.mBitmap.getWidth();
        int image_height = this.mBitmap.getHeight();
        int new_image_width;
        int new_image_height;
        int _screen_width = 640;

        if (image_width >= image_height) {
            if (image_height < _screen_width) {
                new_image_width = (int) ((float) image_width * ((float) _screen_width / (float) image_height));
            } else {
                new_image_width = (int) ((float) image_width / ((float) image_height / (float) _screen_width)); // ok
            }
            this.mBitmap = Bitmap.createScaledBitmap(this.mBitmap, new_image_width, _screen_width, true);

        } else if (image_width < image_height) {
            if (image_width < _screen_width) {
                new_image_height = (int) ((float) image_height * ((float) _screen_width / (float) image_width));
            } else {
                new_image_height = (int) ((float) image_height / ((float) image_width / (float) _screen_width));
            }

            this.mBitmap = Bitmap.createScaledBitmap(mBitmap, _screen_width, new_image_height, true);
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_OK) {
            switch (requestCode) {
            case GALLERY:
                try {
                    Uri selected_image = data.getData();
                    //String selected_image_path = getImagePath(selected_image);

                    String selected_image_path = FileUtils.getPath(this, selected_image);
                    onPhotoTaken(selected_image_path);
                } catch (Exception e) {
                    Toast.makeText(this, R.string.cameracrop_imageload_failed, Toast.LENGTH_LONG).show();
                    e.printStackTrace();
                    finish();
                }

                break;
            case CAMERA:
                File file = new File(_path);
                boolean exists = file.exists();
                if (exists)
                    onPhotoTaken(_path);
                else
                    Toast.makeText(getBaseContext(), R.string.cameracrop_image_fatalerror, Toast.LENGTH_SHORT)
                            .show();
                break;
            default:
                finish();
                break;
            }

        }
        /** if there is no image, just finish the activity */
        else {
            finish();
        }
    }

    protected void onPhotoTaken(final String path) {

        String fileName = Uri.parse(path).getLastPathSegment();
        mFilePath = CameraCropActivity.this.getExternalCacheDir() + "/" + fileName;

        if (!path.equals(mFilePath)) {
            copy(new File(path), new File(mFilePath));
        }

        new AsyncTask<String, Void, byte[]>() {
            boolean loadingFailed = false;

            @Override
            protected byte[] doInBackground(String... params) {
                try {

                    if (!path.equals(mFilePath)) {
                        copy(new File(path), new File(mFilePath));
                    }

                    if (params == null)
                        return null;

                    File f = new File(params[0]);
                    ExifInterface exif = new ExifInterface(f.getPath());
                    int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,
                            ExifInterface.ORIENTATION_NORMAL);

                    int angle = 0;

                    if (orientation == ExifInterface.ORIENTATION_ROTATE_90) {
                        angle = 90;
                    } else if (orientation == ExifInterface.ORIENTATION_ROTATE_180) {
                        angle = 180;
                    } else if (orientation == ExifInterface.ORIENTATION_ROTATE_270) {
                        angle = 270;
                    }

                    Matrix mat = new Matrix();
                    mat.postRotate(angle);

                    BitmapFactory.Options optionsMeta = new BitmapFactory.Options();
                    optionsMeta.inJustDecodeBounds = true;
                    BitmapFactory.decodeFile(f.getAbsolutePath(), optionsMeta);

                    BitmapFactory.Options options = new BitmapFactory.Options();

                    options.inSampleSize = BitmapManagement.calculateInSampleSize(optionsMeta, 640, 640);
                    options.inPurgeable = true;
                    options.inInputShareable = true;
                    mBitmap = BitmapFactory.decodeStream(new FileInputStream(f), null, options);
                    mBitmap = Bitmap.createBitmap(mBitmap, 0, 0, mBitmap.getWidth(), mBitmap.getHeight(), mat,
                            true);
                    _scaleBitmap();
                    return null;
                } catch (Exception ex) {
                    loadingFailed = true;
                    finish();
                }

                return null;
            }

            @Override
            protected void onPostExecute(byte[] result) {
                super.onPostExecute(result);

                if (null != mBitmap) {
                    mImageView.setImageBitmap(mBitmap);
                    mImageView.setScaleType(ScaleType.MATRIX);
                    translateMatrix.setTranslate(-(mBitmap.getWidth() - crop_container_size) / 2f,
                            -(mBitmap.getHeight() - crop_container_size) / 2f);
                    mImageView.setImageMatrix(translateMatrix);

                    matrix = translateMatrix;

                }

            }
        }.execute(mFilePath);

    }

    private boolean saveBitmapToFile(Bitmap bitmap, String path) {
        File file = new File(path);
        FileOutputStream fOut;
        try {
            fOut = new FileOutputStream(file);
            bitmap.compress(Bitmap.CompressFormat.JPEG, 95, fOut);
            fOut.flush();
            fOut.close();
            return true;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;

    }

    private String getImagePath(Uri uri) {
        String[] projection = { MediaStore.Images.Media.DATA };
        Cursor cursor = managedQuery(uri, projection, null, null, null);
        int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        cursor.moveToFirst();
        return cursor.getString(column_index);
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (return_flag)
            finish();
    }

    @Override
    protected void checkIfAppIsInForeground() {
        SpikaApp.gOpenFromBackground = false;
    }

    private void fileUploadAsync(String filePath) {
        new SpikaAsyncTask<Void, Void, ArrayList<String>>(new FileUpload(filePath), new FileUploadFinished(),
                CameraCropActivity.this, true).execute();
    }

    private class FileUpload implements Command<ArrayList<String>> {

        String filePath;

        public FileUpload(String filePath) {
            this.filePath = filePath;
        }

        @Override
        public ArrayList<String> execute() throws JSONException, IOException, SpikaException {
            String tmppath = CameraCropActivity.this.getExternalCacheDir() + "/" + Const.TMP_BITMAP_FILENAME;

            String fileId = CouchDB.uploadFile(filePath);

            Bitmap originalBitmap = BitmapFactory.decodeFile(filePath);
            Bitmap thumbBitmap = Utils.scaleBitmap(originalBitmap, Const.PICTURE_THUMB_SIZE,
                    Const.PICTURE_THUMB_SIZE);
            Utils.saveBitmapToFile(thumbBitmap, tmppath);
            String thumbFileId = CouchDB.uploadFile(tmppath);

            ArrayList<String> list = new ArrayList<String>();
            list.add(fileId);
            list.add(thumbFileId);

            return list;
        }
    }

    private class FileUploadFinished implements ResultListener<ArrayList<String>> {

        @Override
        public void onResultsSucceded(ArrayList<String> result) {
            if (result != null) {
                try {
                    String fileId = result.get(0);
                    String fileThumbId = result.get(1);

                    new SendMessageAsync(getApplicationContext(), SendMessageAsync.TYPE_PHOTO)
                            .execute("Photo", false, false, fileId, fileThumbId).get();

                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (ExecutionException e) {
                    e.printStackTrace();
                }
            } else {
                Logger.debug("FileUploadAsync", "Failed");
            }
            finish();
        }

        @Override
        public void onResultsFail() {
        }
    }

    public void copy(File src, File dst) {
        InputStream in;
        OutputStream out;
        try {
            in = new FileInputStream(src);
            out = new FileOutputStream(dst);

            // Transfer bytes from in to out
            byte[] buf = new byte[1024];
            int len;
            while ((len = in.read(buf)) > 0) {
                out.write(buf, 0, len);
            }

            in.close();
            out.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}