diff --git a/src/android/com/synconset/ImagePicker/ImagePicker.java b/src/android/com/synconset/ImagePicker/ImagePicker.java index ec3822e..a8be003 100644 --- a/src/android/com/synconset/ImagePicker/ImagePicker.java +++ b/src/android/com/synconset/ImagePicker/ImagePicker.java @@ -1,705 +1,72 @@ -/* - * Copyright (c) 2012, David Erosa - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDIN G NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE - * - * Code modified by Andrew Stephan for Sync OnSet - * +/** + * An Image Picker Plugin for Cordova/PhoneGap. */ - package com.synconset; -import java.net.URI; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; +import org.apache.cordova.CallbackContext; +import org.apache.cordova.CordovaPlugin; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; -import com.synconset.FakeR; import android.app.Activity; -import android.app.ActionBar; -import android.app.AlertDialog; -import android.app.LoaderManager; -import android.app.ProgressDialog; -import android.content.Context; -import android.content.CursorLoader; -import android.content.DialogInterface; import android.content.Intent; -import android.content.Loader; -import android.content.res.Resources; -import android.database.Cursor; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.graphics.Color; -import android.graphics.Matrix; -import android.net.Uri; -import android.os.AsyncTask; -import android.os.Bundle; -import android.provider.MediaStore; import android.util.Log; -import android.util.SparseBooleanArray; -import android.view.Display; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.AbsListView; -import android.widget.AbsListView.OnScrollListener; -import android.widget.AdapterView; -import android.widget.AdapterView.OnItemClickListener; -import android.widget.BaseAdapter; -import android.widget.GridView; -import android.widget.ImageView; -import android.widget.TextView; -import org.chromium.ui.resources.Resource; - -import de.awenko.mobile.R; - -public class MultiImageChooserActivity extends Activity implements OnItemClickListener, - LoaderManager.LoaderCallbacks { - private static final String TAG = "ImagePicker"; - - public static final int NOLIMIT = -1; - public static final String MAX_IMAGES_KEY = "MAX_IMAGES"; - public static final String WIDTH_KEY = "WIDTH"; - public static final String HEIGHT_KEY = "HEIGHT"; - public static final String QUALITY_KEY = "QUALITY"; - - private ImageAdapter ia; - - private Cursor imagecursor, actualimagecursor; - private int image_column_index, image_column_orientation, actual_image_column_index, orientation_column_index; - private int colWidth; - - private static final int CURSORLOADER_THUMBS = 0; - private static final int CURSORLOADER_REAL = 1; - - private Map fileNames = new HashMap(); - - private SparseBooleanArray checkStatus = new SparseBooleanArray(); - - private int maxImages; - private int maxImageCount; - - private int desiredWidth; - private int desiredHeight; - private int quality; - - private GridView gridView; - - private final ImageFetcher fetcher = new ImageFetcher(); - - private int selectedColor = 0xff32b2e1; - private boolean shouldRequestThumb = true; - - private FakeR fakeR; - - private ProgressDialog progress; - - private Resources resources; - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - fakeR = new FakeR(this); - setContentView(fakeR.getId("layout", "multiselectorgrid")); - fileNames.clear(); - - maxImages = getIntent().getIntExtra(MAX_IMAGES_KEY, NOLIMIT); - desiredWidth = getIntent().getIntExtra(WIDTH_KEY, 0); - desiredHeight = getIntent().getIntExtra(HEIGHT_KEY, 0); - quality = getIntent().getIntExtra(QUALITY_KEY, 0); - maxImageCount = maxImages; - - Display display = getWindowManager().getDefaultDisplay(); - int width = display.getWidth(); - - colWidth = width / 4; - - gridView = (GridView) findViewById(fakeR.getId("id", "gridview")); - gridView.setOnItemClickListener(this); - gridView.setOnScrollListener(new OnScrollListener() { - private int lastFirstItem = 0; - private long timestamp = System.currentTimeMillis(); - - @Override - public void onScrollStateChanged(AbsListView view, int scrollState) { - if (scrollState == SCROLL_STATE_IDLE) { - shouldRequestThumb = true; - ia.notifyDataSetChanged(); - } - } - - @Override - public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { - float dt = System.currentTimeMillis() - timestamp; - if (firstVisibleItem != lastFirstItem) { - double speed = 1 / dt * 1000; - lastFirstItem = firstVisibleItem; - timestamp = System.currentTimeMillis(); - - // Limit if we go faster than a page a second - shouldRequestThumb = speed < visibleItemCount; - } - } - }); - - ia = new ImageAdapter(this); - gridView.setAdapter(ia); - - resources = getResources(); - - LoaderManager.enableDebugLogging(false); - getLoaderManager().initLoader(CURSORLOADER_THUMBS, null, this); - getLoaderManager().initLoader(CURSORLOADER_REAL, null, this); - setupHeader(); - updateAcceptButton(); - progress = new ProgressDialog(this); - progress.setTitle(resources.getString(R.string.processing_images_header)); - progress.setMessage(resources.getString(R.string.processing_images_message)); - } - - @Override - public void onItemClick(AdapterView arg0, View view, int position, long id) { - String name = getImageName(position); - int rotation = getImageRotation(position); - - if (name == null) { - return; - } - boolean isChecked = !isChecked(position); - if (maxImages == 0 && isChecked) { - isChecked = false; - AlertDialog.Builder builder = new AlertDialog.Builder(this); - builder.setTitle(resources.getString(R.string.maximum_selection_count_error_header)); - builder.setMessage(String.format(resources.getString(R.string.maximum_selection_count_error_message), maxImageCount)); - builder.setPositiveButton("OK", new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - dialog.cancel(); - } - }); - AlertDialog alert = builder.create(); - alert.show(); - } else if (isChecked) { - fileNames.put(name, new Integer(rotation)); - if (maxImageCount == 1) { - this.selectClicked(null); - } else { - maxImages--; - ImageView imageView = (ImageView)view; - if (android.os.Build.VERSION.SDK_INT>=16) { - imageView.setImageAlpha(128); - } else { - imageView.setAlpha(128); - } - view.setBackgroundColor(selectedColor); - } - } else { - fileNames.remove(name); - maxImages++; - ImageView imageView = (ImageView)view; - if (android.os.Build.VERSION.SDK_INT>=16) { - imageView.setImageAlpha(255); - } else { - imageView.setAlpha(255); - } - view.setBackgroundColor(Color.TRANSPARENT); - } - - checkStatus.put(position, isChecked); - updateAcceptButton(); - } - - @Override - public Loader onCreateLoader(int cursorID, Bundle arg1) { - CursorLoader cl = null; - - ArrayList img = new ArrayList(); - switch (cursorID) { - - case CURSORLOADER_THUMBS: - img.add(MediaStore.Images.Media._ID); - img.add(MediaStore.Images.Media.ORIENTATION); - break; - case CURSORLOADER_REAL: - img.add(MediaStore.Images.Thumbnails.DATA); - img.add(MediaStore.Images.Media.ORIENTATION); - break; - default: - break; - } - - cl = new CursorLoader(MultiImageChooserActivity.this, MediaStore.Images.Media.EXTERNAL_CONTENT_URI, - img.toArray(new String[img.size()]), null, null, "DATE_MODIFIED DESC"); - return cl; - } - - @Override - public void onLoadFinished(Loader loader, Cursor cursor) { - if (cursor == null) { - // NULL cursor. This usually means there's no image database yet.... - return; - } - - switch (loader.getId()) { - case CURSORLOADER_THUMBS: - imagecursor = cursor; - image_column_index = imagecursor.getColumnIndex(MediaStore.Images.Media._ID); - image_column_orientation = imagecursor.getColumnIndex(MediaStore.Images.Media.ORIENTATION); - ia.notifyDataSetChanged(); - break; - case CURSORLOADER_REAL: - actualimagecursor = cursor; - String[] columns = actualimagecursor.getColumnNames(); - actual_image_column_index = actualimagecursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); - orientation_column_index = actualimagecursor.getColumnIndexOrThrow(MediaStore.Images.Media.ORIENTATION); - break; - default: - break; - } - } - - @Override - public void onLoaderReset(Loader loader) { - if (loader.getId() == CURSORLOADER_THUMBS) { - imagecursor = null; - } else if (loader.getId() == CURSORLOADER_REAL) { - actualimagecursor = null; - } - } - - public void cancelClicked(View ignored) { - setResult(RESULT_CANCELED); - finish(); - } - - public void selectClicked(View ignored) { - ((TextView) getActionBar().getCustomView().findViewById(fakeR.getId("id", "actionbar_done_textview"))).setEnabled(false); - getActionBar().getCustomView().findViewById(fakeR.getId("id", "actionbar_done")).setEnabled(false); - progress.show(); - Intent data = new Intent(); - if (fileNames.isEmpty()) { - this.setResult(RESULT_CANCELED); - progress.dismiss(); - finish(); - } else { - new ResizeImagesTask().execute(fileNames.entrySet()); - } - } - - - /********************* - * Helper Methods - ********************/ - private void updateAcceptButton() { - ((TextView) getActionBar().getCustomView().findViewById(fakeR.getId("id", "actionbar_done_textview"))) - .setEnabled(fileNames.size() != 0); - getActionBar().getCustomView().findViewById(fakeR.getId("id", "actionbar_done")).setEnabled(fileNames.size() != 0); - } - - private void setupHeader() { - // From Roman Nkk's code - // https://plus.google.com/113735310430199015092/posts/R49wVvcDoEW - // Inflate a "Done/Discard" custom action bar view - /* - * Copyright 2013 The Android Open Source Project - * - * 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. - */ - LayoutInflater inflater = (LayoutInflater) getActionBar().getThemedContext().getSystemService( - LAYOUT_INFLATER_SERVICE); - final View customActionBarView = inflater.inflate(fakeR.getId("layout", "actionbar_custom_view_done_discard"), null); - customActionBarView.findViewById(fakeR.getId("id", "actionbar_done")).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - // "Done" - selectClicked(null); - } - }); - customActionBarView.findViewById(fakeR.getId("id", "actionbar_discard")).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - finish(); - } - }); - - // Show the custom action bar view and hide the normal Home icon and title. - final ActionBar actionBar = getActionBar(); - actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM, ActionBar.DISPLAY_SHOW_CUSTOM - | ActionBar.DISPLAY_SHOW_HOME | ActionBar.DISPLAY_SHOW_TITLE); - actionBar.setCustomView(customActionBarView, new ActionBar.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.MATCH_PARENT)); - } - - private String getImageName(int position) { - actualimagecursor.moveToPosition(position); - String name = null; - - try { - name = actualimagecursor.getString(actual_image_column_index); - } catch (Exception e) { - return null; - } - return name; - } - - private int getImageRotation(int position) { - actualimagecursor.moveToPosition(position); - int rotation = 0; - - try { - rotation = actualimagecursor.getInt(orientation_column_index); - } catch (Exception e) { - return rotation; - } - return rotation; - } - - public boolean isChecked(int position) { - boolean ret = checkStatus.get(position); - return ret; - } - - - /********************* - * Nested Classes - ********************/ - private class SquareImageView extends ImageView { - public SquareImageView(Context context) { - super(context); +public class ImagePicker extends CordovaPlugin { + public static String TAG = "ImagePicker"; + + private CallbackContext callbackContext; + private JSONObject params; + + public boolean execute(String action, final JSONArray args, final CallbackContext callbackContext) throws JSONException { + this.callbackContext = callbackContext; + this.params = args.getJSONObject(0); + if (action.equals("getPictures")) { + Intent intent = new Intent(cordova.getActivity(), MultiImageChooserActivity.class); + int max = 20; + int desiredWidth = 0; + int desiredHeight = 0; + int quality = 100; + if (this.params.has("maximumImagesCount")) { + max = this.params.getInt("maximumImagesCount"); + } + if (this.params.has("width")) { + desiredWidth = this.params.getInt("width"); + } + if (this.params.has("height")) { + desiredWidth = this.params.getInt("height"); + } + if (this.params.has("quality")) { + quality = this.params.getInt("quality"); + } + intent.putExtra("MAX_IMAGES", max); + intent.putExtra("WIDTH", desiredWidth); + intent.putExtra("HEIGHT", desiredHeight); + intent.putExtra("QUALITY", quality); + if (this.cordova != null) { + this.cordova.startActivityForResult((CordovaPlugin) this, intent, 0); + } } - - @Override - public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - super.onMeasure(widthMeasureSpec, widthMeasureSpec); - } - } - - - private class ImageAdapter extends BaseAdapter { - private final Bitmap mPlaceHolderBitmap; - - public ImageAdapter(Context c) { - Bitmap tmpHolderBitmap = BitmapFactory.decodeResource(getResources(), fakeR.getId("drawable", "loading_icon")); - mPlaceHolderBitmap = Bitmap.createScaledBitmap(tmpHolderBitmap, colWidth, colWidth, false); - if (tmpHolderBitmap != mPlaceHolderBitmap) { - tmpHolderBitmap.recycle(); - tmpHolderBitmap = null; - } - } - - public int getCount() { - if (imagecursor != null) { - return imagecursor.getCount(); - } else { - return 0; - } - } - - public Object getItem(int position) { - return position; - } - - public long getItemId(int position) { - return position; - } - - // create a new ImageView for each item referenced by the Adapter - public View getView(int pos, View convertView, ViewGroup parent) { - - if (convertView == null) { - ImageView temp = new SquareImageView(MultiImageChooserActivity.this); - temp.setScaleType(ImageView.ScaleType.CENTER_CROP); - convertView = (View)temp; - } - - ImageView imageView = (ImageView)convertView; - imageView.setImageBitmap(null); - - final int position = pos; - - if (!imagecursor.moveToPosition(position)) { - return imageView; - } - - if (image_column_index == -1) { - return imageView; - } - - final int id = imagecursor.getInt(image_column_index); - final int rotate = imagecursor.getInt(image_column_orientation); - if (isChecked(pos)) { - if (android.os.Build.VERSION.SDK_INT>=16) { - imageView.setImageAlpha(128); - } else { - imageView.setAlpha(128); - } - imageView.setBackgroundColor(selectedColor); - } else { - if (android.os.Build.VERSION.SDK_INT>=16) { - imageView.setImageAlpha(255); - } else { - imageView.setAlpha(255); - } - imageView.setBackgroundColor(Color.TRANSPARENT); - } - if (shouldRequestThumb) { - fetcher.fetch(Integer.valueOf(id), imageView, colWidth, rotate); - } - - return imageView; - } - } - - - private class ResizeImagesTask extends AsyncTask>, Void, ArrayList> { - private Exception asyncTaskError = null; - - @Override - protected ArrayList doInBackground(Set>... fileSets) { - Set> fileNames = fileSets[0]; - ArrayList al = new ArrayList(); - try { - Iterator> i = fileNames.iterator(); - Bitmap bmp; - while(i.hasNext()) { - Entry imageInfo = i.next(); - File file = new File(imageInfo.getKey()); - int rotate = imageInfo.getValue().intValue(); - BitmapFactory.Options options = new BitmapFactory.Options(); - options.inSampleSize = 1; - options.inJustDecodeBounds = true; - BitmapFactory.decodeFile(file.getAbsolutePath(), options); - int width = options.outWidth; - int height = options.outHeight; - float scale = calculateScale(width, height); - if (scale < 1) { - int finalWidth = (int)(width * scale); - int finalHeight = (int)(height * scale); - int inSampleSize = calculateInSampleSize(options, finalWidth, finalHeight); - options = new BitmapFactory.Options(); - options.inSampleSize = inSampleSize; - try { - bmp = this.tryToGetBitmap(file, options, rotate, true); - } catch (OutOfMemoryError e) { - options.inSampleSize = calculateNextSampleSize(options.inSampleSize); - try { - bmp = this.tryToGetBitmap(file, options, rotate, false); - } catch (OutOfMemoryError e2) { - throw new IOException("Unable to load image into memory."); - } - } - } else { - try { - bmp = this.tryToGetBitmap(file, null, rotate, false); - } catch(OutOfMemoryError e) { - options = new BitmapFactory.Options(); - options.inSampleSize = 2; - try { - bmp = this.tryToGetBitmap(file, options, rotate, false); - } catch(OutOfMemoryError e2) { - options = new BitmapFactory.Options(); - options.inSampleSize = 4; - try { - bmp = this.tryToGetBitmap(file, options, rotate, false); - } catch (OutOfMemoryError e3) { - throw new IOException("Unable to load image into memory."); - } - } - } - } - - file = this.storeImage(bmp, file.getName()); - al.add(Uri.fromFile(file).toString()); - } - return al; - } catch(IOException e) { - try { - asyncTaskError = e; - for (int i = 0; i < al.size(); i++) { - URI uri = new URI(al.get(i)); - File file = new File(uri); - file.delete(); - } - } catch(Exception exception) { - // the finally does what we want to do - } finally { - return new ArrayList(); - } - } - } - - @Override - protected void onPostExecute(ArrayList al) { - Intent data = new Intent(); - - if (asyncTaskError != null) { - Bundle res = new Bundle(); - res.putString("ERRORMESSAGE", asyncTaskError.getMessage()); - data.putExtras(res); - setResult(RESULT_CANCELED, data); - } else if (al.size() > 0) { - Bundle res = new Bundle(); - res.putStringArrayList("MULTIPLEFILENAMES", al); - if (imagecursor != null) { - res.putInt("TOTALFILES", imagecursor.getCount()); - } - data.putExtras(res); - setResult(RESULT_OK, data); - } else { - setResult(RESULT_CANCELED, data); - } - - progress.dismiss(); - finish(); - } - - private Bitmap tryToGetBitmap(File file, BitmapFactory.Options options, int rotate, boolean shouldScale) throws IOException, OutOfMemoryError { - Bitmap bmp; - if (options == null) { - bmp = BitmapFactory.decodeFile(file.getAbsolutePath()); - } else { - bmp = BitmapFactory.decodeFile(file.getAbsolutePath(), options); - } - if (bmp == null) { - throw new IOException("The image file could not be opened."); - } - if (options != null && shouldScale) { - float scale = calculateScale(options.outWidth, options.outHeight); - bmp = this.getResizedBitmap(bmp, scale); - } - if (rotate != 0) { - Matrix matrix = new Matrix(); - matrix.setRotate(rotate); - bmp = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), matrix, true); - } - return bmp; - } - - /* - * The following functions are originally from - * https://github.com/raananw/PhoneGap-Image-Resizer - * - * They have been modified by Andrew Stephan for Sync OnSet - * - * The software is open source, MIT Licensed. - * Copyright (C) 2012, webXells GmbH All Rights Reserved. - */ - private File storeImage(Bitmap bmp, String fileName) throws IOException { - int index = fileName.lastIndexOf('.'); - String name = fileName.substring(0, index); - String ext = fileName.substring(index); - File file = File.createTempFile("tmp_" + name, ext); - OutputStream outStream = new FileOutputStream(file); - if (ext.compareToIgnoreCase(".png") == 0) { - bmp.compress(Bitmap.CompressFormat.PNG, quality, outStream); - } else { - bmp.compress(Bitmap.CompressFormat.JPEG, quality, outStream); - } - outStream.flush(); - outStream.close(); - return file; - } - - private Bitmap getResizedBitmap(Bitmap bm, float factor) { - int width = bm.getWidth(); - int height = bm.getHeight(); - // create a matrix for the manipulation - Matrix matrix = new Matrix(); - // resize the bit map - matrix.postScale(factor, factor); - // recreate the new Bitmap - Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, false); - return resizedBitmap; - } - } - - private int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) { - // Raw height and width of image - final int height = options.outHeight; - final int width = options.outWidth; - int inSampleSize = 1; - - if (height > reqHeight || width > reqWidth) { - final int halfHeight = height / 2; - final int halfWidth = width / 2; - - // Calculate the largest inSampleSize value that is a power of 2 and keeps both - // height and width larger than the requested height and width. - while ((halfHeight / inSampleSize) > reqHeight && (halfWidth / inSampleSize) > reqWidth) { - inSampleSize *= 2; - } - } - - return inSampleSize; - } - - private int calculateNextSampleSize(int sampleSize) { - double logBaseTwo = (int)(Math.log(sampleSize) / Math.log(2)); - return (int)Math.pow(logBaseTwo + 1, 2); - } - - private float calculateScale(int width, int height) { - float widthScale = 1.0f; - float heightScale = 1.0f; - float scale = 1.0f; - if (desiredWidth > 0 || desiredHeight > 0) { - if (desiredHeight == 0 && desiredWidth < width) { - scale = (float)desiredWidth/width; - } else if (desiredWidth == 0 && desiredHeight < height) { - scale = (float)desiredHeight/height; - } else { - if (desiredWidth > 0 && desiredWidth < width) { - widthScale = (float)desiredWidth/width; - } - if (desiredHeight > 0 && desiredHeight < height) { - heightScale = (float)desiredHeight/height; - } - if (widthScale < heightScale) { - scale = widthScale; - } else { - scale = heightScale; - } - } - } - - return scale; - } + return true; + } + + public void onActivityResult(int requestCode, int resultCode, Intent data) { + if (resultCode == Activity.RESULT_OK && data != null) { + ArrayList fileNames = data.getStringArrayListExtra("MULTIPLEFILENAMES"); + JSONArray res = new JSONArray(fileNames); + this.callbackContext.success(res); + } else if (resultCode == Activity.RESULT_CANCELED && data != null) { + String error = data.getStringExtra("ERRORMESSAGE"); + this.callbackContext.error(error); + } else if (resultCode == Activity.RESULT_CANCELED) { + JSONArray res = new JSONArray(); + this.callbackContext.success(res); + } else { + this.callbackContext.error("No images selected"); + } + } }