com.foregroundgalleryplugin.ForegroundGalleryLauncher.java Source code

Java tutorial

Introduction

Here is the source code for com.foregroundgalleryplugin.ForegroundGalleryLauncher.java

Source

/*
   Copyright 2012 Bruno Carreira - Lucas Farias - Rafael Luna - Vincius Fonseca. 
    
  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at
    
  http://www.apache.org/licenses/LICENSE-2.0
    
  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
     limitations under the License.            
*/

package com.foregroundgalleryplugin;

import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;

import org.apache.commons.codec.binary.Base64;
import org.apache.cordova.CameraLauncher;
import org.apache.cordova.api.CallbackContext;
import org.apache.cordova.api.CordovaPlugin;
import org.apache.cordova.api.PluginResult;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.content.ContentResolver;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.net.Uri;

public class ForegroundGalleryLauncher extends CameraLauncher {

    private int mQuality; // Compression quality hint (0-100: 0=low quality &
    // high compression, 100=compress of max quality)
    private int targetWidth; // desired width of the image
    private int targetHeight; // desired height of the image   
    public String callbackId;

    /**
     * Executes the request and returns PluginResult.
     *
     * @param action           The action to execute.
     * @param args             JSONArry of arguments for the plugin.
     * @param callbackContext   The callback id used when calling back into JavaScript.
     * @return                 A PluginResult object with a status and message.
     */
    public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {

        this.callbackContext = callbackContext;

        this.targetHeight = 0;
        this.targetWidth = 0;
        this.mQuality = 80;

        JSONObject options = args.optJSONObject(0);
        if (options != null) {
            this.targetHeight = options.getInt("targetHeight");
            this.targetWidth = options.getInt("targetWidth");
            this.mQuality = options.getInt("quality");
        }

        this.getImage();

        PluginResult r = new PluginResult(PluginResult.Status.NO_RESULT);
        r.setKeepCallback(true);
        callbackContext.sendPluginResult(r);
        return true;
    }

    /**
     * Get image from photo library.
     */
    public void getImage() {
        Intent intent = new Intent(this.cordova.getActivity().getApplicationContext(), GalleryActivity.class);
        this.cordova.startActivityForResult((CordovaPlugin) this, intent, 11);
    }

    /**
     * Called when the camera view exits.
     * 
     * @param requestCode
     *            The request code originally supplied to
     *            startActivityForResult(), allowing you to identify who this
     *            result came from.
     * @param resultCode
     *            The integer result code returned by the child activity through
     *            its setResult().
     * @param intent
     *            An Intent, which can return result data to the caller (various
     *            data can be attached to Intent "extras").
     */
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent intent) {

        if (resultCode == Activity.RESULT_OK) {

            Uri uri = intent.getData();
            ContentResolver resolver = this.cordova.getActivity().getContentResolver();

            try {
                Bitmap bitmap = android.graphics.BitmapFactory.decodeStream(resolver.openInputStream(uri));
                bitmap = scaleBitmap(bitmap);
                this.processPicture(bitmap);
                bitmap.recycle();
                bitmap = null;
                System.gc();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
                this.failPicture("Error retrieving image.");
            }
        } else if (resultCode == Activity.RESULT_CANCELED) {
            this.failPicture("Selection cancelled.");
        } else {
            this.failPicture("Selection did not complete!");
        }
    }

    public void processPicture(Bitmap bitmap) {
        ByteArrayOutputStream jpeg_data = new ByteArrayOutputStream();
        try {
            if (bitmap.compress(CompressFormat.JPEG, mQuality, jpeg_data)) {
                byte[] code = jpeg_data.toByteArray();
                byte[] output = Base64.encodeBase64(code);
                String js_out = new String(output);
                this.callbackContext.success("data:image/jpeg;base64," + js_out);
                js_out = null;
                output = null;
                code = null;
            }
        } catch (Exception e) {
            this.failPicture("Error compressing image.");
        }
        jpeg_data = null;
    }

    /**
     * Scales the bitmap according to the requested size.
     * 
     * @param bitmap        The bitmap to scale.
     * @return Bitmap       A new Bitmap object of the same bitmap after scaling. 
     */
    public Bitmap scaleBitmap(Bitmap bitmap) {
        int newWidth = this.targetWidth;
        int newHeight = this.targetHeight;
        int origWidth = bitmap.getWidth();
        int origHeight = bitmap.getHeight();

        // If no new width or height were specified return the original bitmap
        if (newWidth <= 0 && newHeight <= 0) {
            return bitmap;
        }
        // Only the width was specified
        else if (newWidth > 0 && newHeight <= 0) {
            newHeight = (newWidth * origHeight) / origWidth;
        }
        // only the height was specified
        else if (newWidth <= 0 && newHeight > 0) {
            newWidth = (newHeight * origWidth) / origHeight;
        }
        // If the user specified both a positive width and height
        // (potentially different aspect ratio) then the width or height is
        // scaled so that the image fits while maintaining aspect ratio.
        // Alternatively, the specified width and height could have been
        // kept and Bitmap.SCALE_TO_FIT specified when scaling, but this
        // would result in whitespace in the new image.
        else {
            double newRatio = newWidth / (double) newHeight;
            double origRatio = origWidth / (double) origHeight;

            if (origRatio > newRatio) {
                newHeight = (newWidth * origHeight) / origWidth;
            } else if (origRatio < newRatio) {
                newWidth = (newHeight * origWidth) / origHeight;
            }
        }

        return Bitmap.createScaledBitmap(bitmap, newWidth, newHeight, true);
    }

}