com.liwn.zzl.markbit.DrawOptionsMenuActivity.java Source code

Java tutorial

Introduction

Here is the source code for com.liwn.zzl.markbit.DrawOptionsMenuActivity.java

Source

/**
 * Paintroid: An image manipulation application for Android.
 * Copyright (C) 2010-2015 The Catrobat Team
 * (<http://developer.catrobat.org/credits>)
 * <p/>
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 * <p/>
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 * <p/>
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package com.liwn.zzl.markbit;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.Matrix;
import android.media.ExifInterface;
import android.net.Uri;
import android.os.AsyncTask;
import android.provider.MediaStore;
import android.support.v4.app.FragmentActivity;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.MenuItem;
import android.widget.Toast;

import com.liwn.zzl.markbit.dialog.IndeterminateProgressDialog;
import com.liwn.zzl.markbit.dialog.InfoDialog;
import com.liwn.zzl.markbit.dialog.InfoDialog.DialogType;
import com.liwn.zzl.markbit.tools.Tool.StateChange;
import com.liwn.zzl.markbit.tools.implementation.ImportTool;

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

public abstract class DrawOptionsMenuActivity extends AppCompatActivity {

    protected static final int REQUEST_CODE_IMPORTPNG = 1;
    protected static final int REQUEST_CODE_LOAD_PICTURE = 2;
    protected static final int REQUEST_CODE_FINISH = 3;
    protected static final int REQUEST_CODE_TAKE_PICTURE = 4;
    protected static final int REQUEST_CODE_CROP = 5;

    public static final float ACTION_BAR_HEIGHT = 50.0f;

    protected boolean loadBitmapFailed = false;

    public static enum ACTION {
        SAVE, CANCEL
    }

    private static Uri mCameraImageUri;

    protected abstract class RunnableWithBitmap {
        public abstract void run(Bitmap bitmap);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        switch (item.getItemId()) {
        case R.id.menu_item_save_image:
            SaveTask saveTask = new SaveTask(this);
            saveTask.execute();
            break;
        //      case R.id.menu_item_save_copy:
        //         MarkBitApplication.saveCopy = true;
        //         SaveTask saveCopyTask = new SaveTask(this);
        //         saveCopyTask.execute();
        //         break;
        case R.id.menu_item_new_image:
            //         chooseNewImage();
            onNewImage();
            break;

        //      case R.id.menu_item_load_image:
        //         onLoadImage();
        //         break;

        case R.id.menu_item_load_image_from_uri:
            onLoadImageFromFile();
            break;

        case R.id.menu_item_load_image_from_camera:
            onLoadImageFromCamera();
            break;

        default:
            return super.onOptionsItemSelected(item);
        }
        return true;
    }

    private void onLoadImageFromFile() {

        if (!MarkBitApplication.commandManager.hasCommands() && MarkBitApplication.isPlainImage) {
            startLoadImageIntent();
        } else if (MarkBitApplication.isSaved) {
            startLoadImageIntent();
        } else {

            final SaveTask saveTask = new SaveTask(this);

            AlertDialog.Builder alertLoadDialogBuilder = new AlertDialog.Builder(this);
            alertLoadDialogBuilder.setTitle(R.string.menu_load_image).setMessage(R.string.dialog_warning_new_image)
                    .setCancelable(true)
                    .setPositiveButton(R.string.save_button_text, new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int id) {
                            saveTask.execute();
                            startLoadImageIntent();
                        }
                    }).setNegativeButton(R.string.discard_button_text, new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int id) {
                            startLoadImageIntent();
                        }
                    });
            AlertDialog alertLoadImage = alertLoadDialogBuilder.create();
            alertLoadImage.show();
        }
    }

    private void startLoadImageIntent() {
        Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
        intent.setType("image/*");
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
        startActivityForResult(intent, REQUEST_CODE_LOAD_PICTURE);
    }

    private void chooseNewImage() {
        AlertDialog.Builder alertChooseNewBuilder = new AlertDialog.Builder(this);
        alertChooseNewBuilder.setTitle(R.string.menu_new_image).setItems(R.array.new_image,
                new DialogInterface.OnClickListener() {

                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        switch (which) {
                        case 0:
                            onNewImage();
                            break;
                        case 1:
                            onLoadImageFromCamera();
                            break;
                        }
                    }
                });
        AlertDialog alertNew = alertChooseNewBuilder.create();
        alertNew.show();
        return;

    }

    private void onNewImage() {
        if (!MarkBitApplication.commandManager.hasCommands() && MarkBitApplication.isPlainImage) {
            initialiseNewBitmap();
        } else if (MarkBitApplication.isSaved) {
            initialiseNewBitmap();
        } else {

            final SaveTask saveTask = new SaveTask(this);

            AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
            alertDialogBuilder.setTitle(R.string.menu_new_image).setMessage(R.string.dialog_warning_new_image)
                    .setCancelable(true)
                    .setPositiveButton(R.string.save_button_text, new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int id) {
                            saveTask.execute();
                            initialiseNewBitmap();

                        }
                    }).setNegativeButton(R.string.discard_button_text, new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int id) {
                            initialiseNewBitmap();
                        }
                    });
            AlertDialog alertNewImage = alertDialogBuilder.create();
            alertNewImage.show();
        }
    }

    private void onLoadImageFromCamera() {
        if (!MarkBitApplication.commandManager.hasCommands() && MarkBitApplication.isPlainImage) {
            takePhoto();
        } else if (MarkBitApplication.isSaved) {
            takePhoto();
        } else {

            final SaveTask saveTask = new SaveTask(this);

            AlertDialog.Builder newCameraImageAlertDialogBuilder = new AlertDialog.Builder(this);
            newCameraImageAlertDialogBuilder.setTitle(R.string.menu_new_image_from_camera)
                    .setMessage(R.string.dialog_warning_new_image).setCancelable(true)
                    .setPositiveButton(R.string.save_button_text, new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int id) {
                            saveTask.execute();
                            takePhoto();
                        }
                    }).setNegativeButton(R.string.discard_button_text, new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int id) {
                            takePhoto();
                        }
                    });
            AlertDialog alertNewCameraImage = newCameraImageAlertDialogBuilder.create();
            alertNewCameraImage.show();
        }
    }

    // TODO fix camera rotation bugs in xiaomi smartphone
    private Uri rotateNormal(Uri uri) throws IOException {
        ExifInterface exif = new ExifInterface(uri.getPath());
        int rotation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
        int rotationInDegrees = exifToDegrees(rotation);
        Matrix matrix = new Matrix();
        if (rotation != 0) {
            matrix.preRotate(rotationInDegrees);
        }
        Bitmap srcBitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), uri);
        Bitmap adjustedBitmap = Bitmap.createBitmap(srcBitmap, 0, 0, MarkBitApplication.BIT_LCD_WIDTH,
                MarkBitApplication.BIT_LCD_HEIGHT, matrix, true);
        ByteArrayOutputStream bytes = new ByteArrayOutputStream();
        adjustedBitmap.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
        String path = MediaStore.Images.Media.insertImage(this.getContentResolver(), adjustedBitmap, "Title", null);
        return Uri.parse(path);
    }

    private static int exifToDegrees(int exifOrientation) {
        if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_90) {
            return 90;
        } else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_180) {
            return 180;
        } else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_270) {
            return 270;
        }
        return 0;
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (resultCode == Activity.RESULT_OK) {
            switch (requestCode) {
            case REQUEST_CODE_LOAD_PICTURE:
                mCameraImageUri = data.getData();
                try {
                    Bitmap bitmap = BitmapFactory
                            .decodeStream(getContentResolver().openInputStream(mCameraImageUri));
                    // crop cannot resize images smaller than 50*50
                    if (bitmap.getWidth() > 50 && bitmap.getHeight() > 50) {
                        cropImage(mCameraImageUri);
                        MarkBitApplication.saveCopy = true;
                    } else {
                        loadBitmapFromUri(mCameraImageUri);
                        MarkBitApplication.isPlainImage = false;
                        MarkBitApplication.isSaved = false;
                        MarkBitApplication.savedPictureUri = null;
                    }
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                }

                break;
            case REQUEST_CODE_TAKE_PICTURE:
                // fixed the rotate bugs for some android device
                //                  mCameraImageUri = rotateNormal(mCameraImageUri);
                cropImage(mCameraImageUri);
                break;
            case REQUEST_CODE_CROP:
                if (data != null) {
                    loadBitmapFromUri(data.getData());
                    MarkBitApplication.isPlainImage = false;
                    MarkBitApplication.isSaved = false;
                    MarkBitApplication.savedPictureUri = null;
                }
                break;
            }

        }
    }

    private void cropImage(Uri uri) {
        File file = FileIO.getFile(this, uri);
        Uri tmp = Uri.fromFile(file);

        Intent intent = new Intent("com.android.camera.action.CROP");
        intent.setDataAndType(tmp, "image/*");
        intent.putExtra("crop", "true");
        intent.putExtra("aspectX", 1);
        intent.putExtra("aspectY", 1);
        intent.putExtra("outputX", MarkBitApplication.BIT_LCD_WIDTH);
        intent.putExtra("outputY", MarkBitApplication.BIT_LCD_HEIGHT);
        intent.putExtra("scale", true);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
        intent.putExtra("noFaceDetection", true);
        intent.putExtra("return-data", false);
        intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
        startActivityForResult(intent, REQUEST_CODE_CROP);
    }

    protected void takePhoto() {
        File tempFile = FileIO.createNewEmptyPictureFile(DrawOptionsMenuActivity.this, FileIO.getDefaultFileName());
        if (tempFile != null) {
            mCameraImageUri = Uri.fromFile(tempFile);
        }
        if (mCameraImageUri == null) {
            new InfoDialog(DialogType.WARNING, R.string.dialog_error_sdcard_text, R.string.dialog_error_save_title)
                    .show(getSupportFragmentManager(), "savedialogerror");
            return;
        }
        //        Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, mCameraImageUri);
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
        startActivityForResult(intent, REQUEST_CODE_TAKE_PICTURE);
        //        intent.putExtra(MediaStore.EXTRA_OUTPUT, mCameraImageUri);
        //        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
        //        startActivityForResult(intent, REQUEST_CODE_TAKE_PICTURE);
    }

    protected void loadBitmapFromUriAndRun(final Uri uri, final RunnableWithBitmap runnable) {
        String loadMessge = getResources().getString(R.string.dialog_load);
        final ProgressDialog dialog = ProgressDialog.show(DrawOptionsMenuActivity.this, "", loadMessge, true);

        Thread thread = new Thread("loadBitmapFromUriAndRun") {
            @Override
            public void run() {
                Bitmap bitmap = null;
                try {
                    bitmap = FileIO.getBitmapFromUri(uri);
                } catch (Exception e) {
                    loadBitmapFailed = true;
                }

                if (bitmap != null) {
                    runnable.run(bitmap);
                } else {
                    loadBitmapFailed = true;
                }
                dialog.dismiss();
                MarkBitApplication.currentTool.resetInternalState(StateChange.NEW_IMAGE_LOADED);
                if (loadBitmapFailed) {
                    loadBitmapFailed = false;
                    new InfoDialog(DialogType.WARNING, R.string.dialog_loading_image_failed_title,
                            R.string.dialog_loading_image_failed_text).show(getSupportFragmentManager(),
                                    "loadbitmapdialogerror");
                } else {
                    if (!(MarkBitApplication.currentTool instanceof ImportTool)) {
                        MarkBitApplication.savedPictureUri = uri;
                    }
                }
            }
        };
        thread.start();
    }

    // if needed use Async Task
    public void saveFile() {

        Bitmap bitmap = MarkBitApplication.drawingSurface.getBitmapCopy();
        if (!FileIO.saveBitmap(this, bitmap)) {

            // save failed!
            new InfoDialog(DialogType.WARNING, R.string.dialog_error_sdcard_text, R.string.dialog_error_save_title)
                    .show(getSupportFragmentManager(), "savedialogerror");
        }

        MarkBitApplication.isSaved = true;
    }

    protected void loadBitmapFromUri(Uri uri) {
        if (uri == null || uri.toString().length() < 1) {
            Log.e(MarkBitApplication.TAG, "BAD URI: cannot load image");
            return;
        }

        loadBitmapFromUriAndRun(uri, new RunnableWithBitmap() {
            @Override
            public void run(Bitmap bitmap) {
                MarkBitApplication.drawingSurface.resetBitmap(bitmap);
                MarkBitApplication.perspective.resetScaleAndTranslation();
            }
        });
    }

    protected void initialiseWithMarkPath(String markPath) {
        //        File file = FileIO.getFileByPath(markPath);
        File file = new File(markPath);

        if (file != null) {
            Bitmap bitmap = BitmapFactory.decodeFile(markPath);
            initialiseWithBitmap(bitmap.copy(Config.ARGB_8888, true));
        } else {
            Log.e("Initialise by Mark ID: ", "faild for file is null");
            initialiseNewBitmap();
        }
    }

    protected void initialiseWithBitmap(Bitmap bitmap) {
        MarkBitApplication.drawingSurface.resetBitmap(bitmap);
        MarkBitApplication.perspective.resetScaleAndTranslation();
        MarkBitApplication.currentTool.resetInternalState(StateChange.NEW_IMAGE_LOADED);
        MarkBitApplication.isPlainImage = true;
        MarkBitApplication.isSaved = false;
        MarkBitApplication.savedPictureUri = null;
    }

    protected void initialiseNewBitmap() {
        float width = MarkBitApplication.BIT_LCD_WIDTH;
        float height = MarkBitApplication.BIT_LCD_HEIGHT;
        Log.d("PAINTROID - MFA", "init new bitmap with: w: " + width + " h:" + height);
        Bitmap bitmap = Bitmap.createBitmap((int) width, (int) height, Config.ARGB_8888);
        bitmap.eraseColor(Color.TRANSPARENT);
        initialiseWithBitmap(bitmap);
    }

    protected class SaveTask extends AsyncTask<String, Void, Void> {

        private DrawOptionsMenuActivity context;

        public SaveTask(DrawOptionsMenuActivity context) {
            this.context = context;
        }

        @Override
        protected void onPreExecute() {
            IndeterminateProgressDialog.getInstance().show();
            Log.d(MarkBitApplication.TAG,
                    "async tast prgDialog isShowing" + IndeterminateProgressDialog.getInstance().isShowing());
        }

        @Override
        protected Void doInBackground(String... arg0) {
            saveFile();
            return null;
        }

        @Override
        protected void onPostExecute(Void Result) {
            IndeterminateProgressDialog.getInstance().dismiss();
            if (!MarkBitApplication.saveCopy) {
                Toast.makeText(context, R.string.saved, Toast.LENGTH_LONG).show();
            } else {
                if (MarkBitApplication.drawMenu.findItem(R.id.menu_item_save_image) != null) {
                    MarkBitApplication.drawMenu.findItem(R.id.menu_item_save_image).setVisible(true);
                }
                Toast.makeText(context, R.string.copy, Toast.LENGTH_LONG).show();
                MarkBitApplication.saveCopy = false;
            }
        }
    }
}