com.ichi2.anki.multimediacard.fields.BasicImageFieldController.java Source code

Java tutorial

Introduction

Here is the source code for com.ichi2.anki.multimediacard.fields.BasicImageFieldController.java

Source

/****************************************************************************************
 * Copyright (c) 2013 Bibek Shrestha <bibekshrestha@gmail.com>                          *
 * Copyright (c) 2013 Zaur Molotnikov <qutorial@gmail.com>                              *
 * Copyright (c) 2013 Nicolas Raoul <nicolas.raoul@gmail.com>                           *
 * Copyright (c) 2013 Flavio Lerda <flerda@gmail.com>                                   *
 *                                                                                      *
 * This program is free software; you can redistribute it and/or modify it under        *
 * the terms of the GNU General Public License as published by the Free Software        *
 * Foundation; either version 3 of the License, or (at your option) any later           *
 * version.                                                                             *
 *                                                                                      *
 * 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 General Public License for more details.             *
 *                                                                                      *
 * You should have received a copy of the GNU General Public License along with         *
 * this program.  If not, see <http://www.gnu.org/licenses/>.                           *
 ****************************************************************************************/

package com.ichi2.anki.multimediacard.fields;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.net.Uri;
import android.provider.MediaStore;
import android.provider.MediaStore.MediaColumns;
import android.support.v4.content.FileProvider;
import android.util.DisplayMetrics;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;

import com.ichi2.anki.R;
import com.ichi2.compat.CompatHelper;
import com.ichi2.utils.BitmapUtil;
import com.ichi2.utils.ExifUtil;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

import timber.log.Timber;

public class BasicImageFieldController extends FieldControllerBase implements IFieldController {

    protected static final int ACTIVITY_SELECT_IMAGE = 1;
    protected static final int ACTIVITY_TAKE_PICTURE = 2;
    protected static final int IMAGE_PREVIEW_MAX_WIDTH = 100;
    private static final int IMAGE_SAVE_MAX_WIDTH = 1920;

    protected Button mBtnGallery;
    protected Button mBtnCamera;
    protected ImageView mImagePreview;

    protected String mTempCameraImagePath;
    private DisplayMetrics mMetrics = null;

    private int getMaxImageSize() {
        DisplayMetrics metrics = getDisplayMetrics();

        int height = metrics.heightPixels;
        int width = metrics.widthPixels;

        return (int) Math.min(height * 0.4, width * 0.6);
    }

    @Override
    public void createUI(Context context, LinearLayout layout) {
        mImagePreview = new ImageView(mActivity);

        DisplayMetrics metrics = getDisplayMetrics();

        int height = metrics.heightPixels;
        int width = metrics.widthPixels;

        LinearLayout.LayoutParams p = new LayoutParams(android.view.ViewGroup.LayoutParams.FILL_PARENT,
                android.view.ViewGroup.LayoutParams.WRAP_CONTENT);
        setPreviewImage(mField.getImagePath(), getMaxImageSize());
        mImagePreview.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
        mImagePreview.setAdjustViewBounds(true);

        mImagePreview.setMaxHeight((int) Math.round(height * 0.4));
        mImagePreview.setMaxWidth((int) Math.round(width * 0.6));

        mBtnGallery = new Button(mActivity);
        mBtnGallery.setText(gtxt(R.string.multimedia_editor_image_field_editing_galery));
        mBtnGallery.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent i = new Intent(Intent.ACTION_PICK,
                        android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                mActivity.startActivityForResult(i, ACTIVITY_SELECT_IMAGE);
            }
        });

        mBtnCamera = new Button(mActivity);
        mBtnCamera.setText(gtxt(R.string.multimedia_editor_image_field_editing_photo));
        mBtnCamera.setOnClickListener(new View.OnClickListener() {
            @SuppressLint("NewApi")
            @Override
            public void onClick(View v) {
                Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
                File image;
                File storageDir;
                String timeStamp = new SimpleDateFormat("yyyyMMddHHmmss", Locale.US).format(new Date());
                try {
                    storageDir = mActivity.getCacheDir();
                    image = File.createTempFile("img_" + timeStamp, ".jpg", storageDir);
                    mTempCameraImagePath = image.getPath();
                    Uri uriSavedImage = FileProvider.getUriForFile(mActivity,
                            mActivity.getApplicationContext().getPackageName() + ".apkgfileprovider", image);

                    cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, uriSavedImage);
                    mActivity.startActivityForResult(cameraIntent, ACTIVITY_TAKE_PICTURE);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });
        // Chromebooks do not support camera capture yet.
        if (CompatHelper.isChromebook()) {
            mBtnCamera.setVisibility(View.INVISIBLE);
        }

        layout.addView(mImagePreview, android.view.ViewGroup.LayoutParams.FILL_PARENT, p);
        layout.addView(mBtnGallery, android.view.ViewGroup.LayoutParams.FILL_PARENT);
        layout.addView(mBtnCamera, android.view.ViewGroup.LayoutParams.FILL_PARENT);
    }

    private String gtxt(int id) {
        return mActivity.getText(id).toString();
    }

    protected DisplayMetrics getDisplayMetrics() {
        if (mMetrics == null) {
            mMetrics = new DisplayMetrics();
            mActivity.getWindowManager().getDefaultDisplay().getMetrics(mMetrics);
        }
        return mMetrics;
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode == Activity.RESULT_CANCELED) {
            // Do Nothing.
        } else if (requestCode == ACTIVITY_SELECT_IMAGE) {
            Uri selectedImage = data.getData();
            // Timber.d(selectedImage.toString());
            String[] filePathColumn = { MediaColumns.DATA };

            Cursor cursor = mActivity.getContentResolver().query(selectedImage, filePathColumn, null, null, null);
            cursor.moveToFirst();

            int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
            String filePath = cursor.getString(columnIndex);
            cursor.close();

            mField.setImagePath(filePath);
        } else if (requestCode == ACTIVITY_TAKE_PICTURE) {
            String imagePath = rotateAndCompress(mTempCameraImagePath);
            mField.setImagePath(imagePath);
            mField.setHasTemporaryMedia(true);
        }
        setPreviewImage(mField.getImagePath(), getMaxImageSize());
    }

    @Override
    public void onFocusLost() {

    }

    @Override
    public void onDone() {
        //
    }

    private String rotateAndCompress(String inPath) {
        // Set the rotation of the camera image and save as png
        File f = new File(inPath);
        // use same filename but with png extension for output file
        String outPath = inPath.substring(0, inPath.lastIndexOf(".")) + ".png";
        // Load into a bitmap with max size of 1920 pixels and rotate if necessary
        Bitmap b = BitmapUtil.decodeFile(f, IMAGE_SAVE_MAX_WIDTH);
        FileOutputStream out = null;
        try {
            out = new FileOutputStream(outPath);
            b = ExifUtil.rotateFromCamera(f, b);
            b.compress(Bitmap.CompressFormat.PNG, 90, out);
            f.delete();
            return outPath;
        } catch (FileNotFoundException e) {
            Timber.e("Error in BasicImageFieldController.rotateAndCompress() : " + e.getMessage());
            return inPath;
        } finally {
            try {
                if (out != null) {
                    out.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    protected void setPreviewImage(String imagePath, int maxsize) {
        if (imagePath != null && !imagePath.equals("")) {
            // Caused bug on API <= 7
            // mImagePreview.setImageURI(Uri.fromFile(new File(imagePath)));

            // fix but crashes with out of memory
            // mImagePreview.setImageURI(Uri.parse(new File(imagePath).toString()));

            // fix for both
            File f = new File(imagePath);

            Bitmap b = BitmapUtil.decodeFile(f, maxsize);

            int currentapiVersion = android.os.Build.VERSION.SDK_INT;
            if (currentapiVersion >= android.os.Build.VERSION_CODES.ECLAIR) {
                b = ExifUtil.rotateFromCamera(f, b);
            }

            mImagePreview.setImageBitmap(b);
        }
    }

    @Override
    public void onDestroy() {
        ImageView imageView = mImagePreview;
        BitmapUtil.freeImageView(imageView);
    }

}