/**
   * 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;

    if (action.equals("takePicture")) {
      int srcType = CAMERA;
      int destType = FILE_URI;
      this.saveToPhotoAlbum = false;
      this.targetHeight = 0;
      this.targetWidth = 0;
      this.encodingType = JPEG;
      this.mediaType = PICTURE;
      this.mQuality = 80;

      this.mQuality = args.getInt(0);
      destType = args.getInt(1);
      srcType = args.getInt(2);
      this.targetWidth = args.getInt(3);
      this.targetHeight = args.getInt(4);
      this.encodingType = args.getInt(5);
      this.mediaType = args.getInt(6);
      // this.allowEdit = args.getBoolean(7); // This field is unused.
      this.correctOrientation = args.getBoolean(8);
      this.saveToPhotoAlbum = args.getBoolean(9);

      // If the user specifies a 0 or smaller width/height
      // make it -1 so later comparisons succeed
      if (this.targetWidth < 1) {
        this.targetWidth = -1;
      }
      if (this.targetHeight < 1) {
        this.targetHeight = -1;
      }

      try {
        if (srcType == CAMERA) {
          this.takePicture(destType, encodingType);
        } else if ((srcType == PHOTOLIBRARY) || (srcType == SAVEDPHOTOALBUM)) {
          this.getImage(srcType, destType);
        }
      } catch (IllegalArgumentException e) {
        callbackContext.error("Illegal Argument Exception");
        PluginResult r = new PluginResult(PluginResult.Status.ERROR);
        callbackContext.sendPluginResult(r);
        return true;
      }

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

      return true;
    }
    return false;
  }
  private boolean invokeBlinkup(
      final Activity activity, final BlinkupController controller, JSONArray data) {
    int timeoutMs;
    try {
      mApiKey = data.getString(BLINKUP_ARG_API_KEY);
      mDeveloperPlanId = data.getString(BLINKUP_ARG_DEVELOPER_PLAN_ID);
      timeoutMs = data.getInt(BLINKUP_ARG_TIMEOUT_MS);
      mGeneratePlanId = data.getBoolean(BLINKUP_ARG_GENERATE_PLAN_ID);
    } catch (JSONException exc) {
      BlinkUpPluginResult.sendPluginErrorToCallback(ERROR_INVALID_ARGUMENTS);
      return false;
    }

    // if api key not valid, send error message and quit
    if (!apiKeyFormatValid()) {
      BlinkUpPluginResult.sendPluginErrorToCallback(ERROR_INVALID_API_KEY);
      return false;
    }

    Intent blinkupCompleteIntent = new Intent(activity, BlinkUpCompleteActivity.class);
    blinkupCompleteIntent.putExtra(Extras.EXTRA_DEVELOPER_PLAN_ID, mDeveloperPlanId);
    blinkupCompleteIntent.putExtra(Extras.EXTRA_TIMEOUT_MS, timeoutMs);
    controller.intentBlinkupComplete = blinkupCompleteIntent;

    // default is to run on WebCore thread, we have UI so need UI thread
    activity.runOnUiThread(
        new Runnable() {
          @Override
          public void run() {
            presentBlinkUp(activity, controller);
          }
        });
    return true;
  }
 public List<Object> parseJSONArray(JSONArray values, Table table) throws ParseException {
   List<Object> parsedValues = new ArrayList<>();
   for (int i = 0; i < table.getColumnsCount(); i++) {
     Class<?> type = table.getColumnType(i);
     Object val = values.get(i);
     if (val.equals(null)) {
       parsedValues.add(null);
     } else if (type == Integer.class && val.getClass() == Integer.class) {
       parsedValues.add(values.getInt(i));
     } else if (type == Long.class
         && (val.getClass() == Long.class || val.getClass() == Integer.class)) {
       parsedValues.add(values.getLong(i));
     } else if (type == Byte.class && val.getClass() == Integer.class) {
       Integer a = values.getInt(i);
       parsedValues.add(a.byteValue());
     } else if (type == Float.class && val.getClass() == Double.class) {
       Double a = values.getDouble(i);
       parsedValues.add(a.floatValue());
     } else if (type == Double.class && val.getClass() == Double.class) {
       parsedValues.add(values.getDouble(i));
     } else if (type == Boolean.class && val.getClass() == Boolean.class) {
       parsedValues.add(values.getBoolean(i));
     } else if (type == String.class && val.getClass() == String.class) {
       parsedValues.add(val);
     } else {
       throw new ParseException("types mismatch", 0);
     }
   }
   return parsedValues;
 }
  private static List<?> getList(JSONArray jsonArray, Class<?> childrenType)
      throws JSONException, IllegalAccessException, InstantiationException {

    List<Object> list = new Vector<Object>(jsonArray.length());

    for (int i = 0; i < jsonArray.length(); i++) {

      Object child = null;

      if (childrenType == List.class) {
        child = getList(jsonArray.getJSONArray(i), childrenType);

      } else if (childrenType == String.class) {
        child = jsonArray.getString(i);

      } else if (childrenType == boolean.class || childrenType == Boolean.class) {
        child = jsonArray.getBoolean(i);

      } else if (childrenType == int.class || childrenType == Integer.class) {
        child = jsonArray.getInt(i);

      } else if (childrenType == double.class || childrenType == Double.class) {
        child = jsonArray.getDouble(i);

      } else {
        child = childrenType.newInstance();
        reflectJsonObject(child, jsonArray.getJSONObject(i));
      }

      list.add(child);
    }

    return list;
  }
 /**
  * set geodesic
  *
  * @param args
  * @param callbackContext
  * @throws JSONException
  */
 @SuppressWarnings("unused")
 private void setGeodesic(final JSONArray args, final CallbackContext callbackContext)
     throws JSONException {
   String id = args.getString(1);
   boolean isGeodisic = args.getBoolean(2);
   this.setBoolean("setGeodesic", id, isGeodisic, callbackContext);
 }
  @Override
  public PluginResult execute(String action, JSONArray args, String callbackId) {
    // Log.d("MindSetPlugin", "Plugin Called");
    PluginResult result = null;
    PluginResult.Status status = PluginResult.Status.OK;

    try {
      if (START_ACTION.equals(action)) {
        // Log.d("MindSetPlugin", "Start passed");
        String o =
            start(
                args.getString(0),
                args.getBoolean(1),
                args.getInt(2),
                args.getInt(3),
                args.getString(4));
        result = new PluginResult(status, o);

      } else if (STOP_ACTION.equals(action)) {
        // Log.d("MindSetPlugin", "Stop passed");
        stop(args.getString(0));
        result = new PluginResult(status, "");

      } else {
        result = new PluginResult(Status.INVALID_ACTION);
        // Log
        //		.d("MindSetPlugin", "Invalid action : " + action
        //				+ " passed");
      }
    } catch (JSONException ex) {
    }
    return result;
  }
Beispiel #7
0
  /**
   * Executes the request and returns PluginResult.
   *
   * @param action The action to execute.
   * @param args JSONArry of arguments for the plugin.
   * @param callbackContext The callback context from which we were invoked.
   * @return A PluginResult object with a status and message.
   */
  public boolean execute(String action, JSONArray args, CallbackContext callbackContext)
      throws JSONException {
    PluginResult.Status status = PluginResult.Status.OK;
    String result = "";

    try {
      if (action.equals("clearCache")) {
        this.clearCache();
      } else if (action.equals("show")) {
        // This gets called from JavaScript onCordovaReady to show the webview.
        // I recommend we change the name of the Message as spinner/stop is not
        // indicative of what this actually does (shows the webview).
        cordova
            .getActivity()
            .runOnUiThread(
                new Runnable() {
                  public void run() {
                    webView.postMessage("spinner", "stop");
                  }
                });
      } else if (action.equals("loadUrl")) {
        this.loadUrl(args.getString(0), args.optJSONObject(1));
      } else if (action.equals("cancelLoadUrl")) {
        // this.cancelLoadUrl();
      } else if (action.equals("clearHistory")) {
        this.clearHistory();
      } else if (action.equals("backHistory")) {
        this.backHistory();
      } else if (action.equals("overrideButton")) {
        this.overrideButton(args.getString(0), args.getBoolean(1));
      } else if (action.equals("overrideBackbutton")) {
        this.overrideBackbutton(args.getBoolean(0));
      } else if (action.equals("exitApp")) {
        this.exitApp();
      }
      callbackContext.sendPluginResult(new PluginResult(status, result));
      return true;
    } catch (JSONException e) {
      callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
      return false;
    }
  }
  public DiffData readDiffData(String source) throws ReviewboardException {

    try {
      JSONObject jsonDiffData = checkedGetJSonRootObject(source).getJSONObject("diff_data");

      DiffData diffData = new DiffData();
      diffData.setBinary(jsonDiffData.getBoolean("binary"));
      diffData.setNewFile(jsonDiffData.getBoolean("new_file"));
      diffData.setNumChanges(jsonDiffData.getInt("num_changes"));

      JSONArray changedChunkIndexes = jsonDiffData.getJSONArray("changed_chunk_indexes");
      for (int i = 0; i < changedChunkIndexes.length(); i++)
        diffData.getChangedChunkIndexes().add(changedChunkIndexes.getInt(i));

      JSONArray chunks = jsonDiffData.getJSONArray("chunks");
      for (int i = 0; i < chunks.length(); i++) {

        JSONObject jsonChunk = chunks.getJSONObject(i);

        Chunk chunk = new Chunk();
        chunk.setChange(Type.fromString(jsonChunk.getString("change")));
        chunk.setCollapsable(jsonChunk.getBoolean("collapsable"));
        chunk.setIndex(jsonChunk.getInt("index"));
        chunk.setNumLines(jsonChunk.getInt("numlines"));

        JSONArray lines = jsonChunk.getJSONArray("lines");
        for (int j = 0; j < lines.length(); j++) {

          JSONArray lineArray = lines.getJSONArray(j);

          Line line = new Line();
          line.setDiffRowNumber(lineArray.getInt(0));
          line.setLeftFileRowNumber(getPossiblyEmptyInt(lineArray, 1));
          line.setLeftLineText(lineArray.getString(2));

          line.setRightFileRowNumber(getPossiblyEmptyInt(lineArray, 4));
          line.setRightLineText(lineArray.getString(5));

          line.setWhitespaceOnly(lineArray.getBoolean(7));

          chunk.getLines().add(line);
        }

        diffData.getChunks().add(chunk);
      }

      return diffData;
    } catch (JSONException e) {
      throw new ReviewboardException(e.getMessage(), e);
    }
  }
 void setDebugMode(JSONArray data, CallbackContext callbackContext) {
   boolean mode;
   try {
     mode = data.getBoolean(0);
     // if (mode.equals("true")) {
     // 	JPushInterface.setDebugMode(true);
     // } else if (mode.equals("false")) {
     // 	JPushInterface.setDebugMode(false);
     // } else {
     // 	callbackContext.error("error mode");
     // }
     JPushInterface.setDebugMode(mode);
     callbackContext.success();
   } catch (JSONException e) {
   }
 }
  public static GameAction deserializeGameAction(JSONObject actionObject) {
    GameActionType type = GameActionType.valueOf(actionObject.getString("type"));
    String sender = actionObject.getString("sender");

    switch (type) {
      case REROLL:
        JSONArray diceArray = actionObject.getJSONArray("dice");
        boolean[] dice = new boolean[diceArray.length()];
        for (int i = 0; i < dice.length; i++) dice[i] = diceArray.getBoolean(i);
        return new RerollAction(sender, dice);
      case JOIN_ROOM:
        return new JoinRoomAction(sender, actionObject.getString("room"));
      default:
        return new GameAction(type, sender);
    }
  }
	@Override
	public boolean execute(String action, JSONArray data,
			CallbackContext callbackContext) throws JSONException {
		if (action.equals("init")) {
			init();
		}
		if (action.equals("setDebugMode")) {
			boolean mode = data.getBoolean(0);
			setDebugMode(mode);
		}
		if (action.equals("onKillProcess")) {
			onKillProcess();
		}
		callbackContext.success();
		return true;
	}
 private boolean[] getBooleanArray(JSONObject aObject, String aName) {
   JSONArray items = new JSONArray();
   try {
     items = aObject.getJSONArray(aName);
   } catch (Exception ex) {
     return null;
   }
   int length = items.length();
   boolean[] list = new boolean[length];
   for (int i = 0; i < length; i++) {
     try {
       list[i] = items.getBoolean(i);
     } catch (Exception ex) {
     }
   }
   return list;
 }
 public void testMessageWithExecute() throws IOException, JSONException {
   StringWriter stringWriter = new StringWriter();
   PrintWriter printWriter = new PrintWriter(stringWriter);
   ProtocolMessageWriter writer = new JsonMessageWriter(printWriter);
   String methodName = "methodName";
   Display display = new Display();
   Shell shell = new Shell(display);
   writer.addExecutePayload(WidgetUtil.getId(shell), methodName, new Object[] {"a", "b"});
   String widgetId = WidgetUtil.getId(shell);
   String actual = stringWriter.getBuffer().toString();
   JSONObject message = new JSONObject(actual + "]}");
   JSONArray widgets = message.getJSONArray(IProtocolConstants.MESSAGE_WIDGETS);
   JSONObject widgetObject = widgets.getJSONObject(0);
   String actualId = widgetObject.getString(IProtocolConstants.WIDGETS_ID);
   assertEquals(widgetId, actualId);
   String type = widgetObject.getString(IProtocolConstants.WIDGETS_TYPE);
   assertEquals(IProtocolConstants.PAYLOAD_EXECUTE, type);
   JSONObject payload = widgetObject.getJSONObject(IProtocolConstants.WIDGETS_PAYLOAD);
   String actualMethod = payload.getString(IProtocolConstants.KEY_METHODNAME);
   assertEquals(methodName, actualMethod);
   JSONArray actualParams = payload.getJSONArray(IProtocolConstants.KEY_PARAMETER_LIST);
   assertEquals("a", actualParams.getString(0));
   assertEquals("b", actualParams.getString(1));
   Object[] array = new Object[] {new Integer(5), "b", new Boolean(false)};
   writer.addExecutePayload(WidgetUtil.getId(shell), methodName, array);
   writer.finish();
   actual = stringWriter.getBuffer().toString();
   message = new JSONObject(actual);
   JSONArray widgetArray = message.getJSONArray(IProtocolConstants.MESSAGE_WIDGETS);
   widgetObject = widgetArray.getJSONObject(1);
   type = widgetObject.getString(IProtocolConstants.WIDGETS_TYPE);
   assertEquals(IProtocolConstants.PAYLOAD_EXECUTE, type);
   actualId = widgetObject.getString(IProtocolConstants.WIDGETS_ID);
   assertEquals(widgetId, actualId);
   payload = widgetObject.getJSONObject(IProtocolConstants.WIDGETS_PAYLOAD);
   actualMethod = payload.getString(IProtocolConstants.KEY_METHODNAME);
   assertEquals(methodName, actualMethod);
   JSONArray params = payload.getJSONArray(IProtocolConstants.KEY_PARAMETER_LIST);
   assertEquals(5, params.getInt(0));
   assertEquals("b", params.getString(1));
   assertFalse(params.getBoolean(2));
 }
 private void checkButtonConstruct(
     final Button button, final String shellId, final String buttonId, final JSONObject message)
     throws JSONException {
   JSONArray widgetArray = message.getJSONArray(IProtocolConstants.MESSAGE_WIDGETS);
   JSONObject widgetObject = widgetArray.getJSONObject(3);
   String actualButtonId = widgetObject.getString(IProtocolConstants.WIDGETS_ID);
   assertEquals(buttonId, actualButtonId);
   String type = widgetObject.getString(IProtocolConstants.WIDGETS_TYPE);
   assertEquals(IProtocolConstants.PAYLOAD_CONSTRUCT, type);
   JSONObject payload = widgetObject.getJSONObject(IProtocolConstants.WIDGETS_PAYLOAD);
   String actualShellId = payload.getString(IProtocolConstants.KEY_PARENT_ID);
   assertEquals(shellId, actualShellId);
   JSONArray params = payload.getJSONArray(IProtocolConstants.KEY_PARAMETER_LIST);
   assertEquals(4, params.getInt(0));
   assertTrue(params.getBoolean(1));
   type = payload.getString(IProtocolConstants.KEY_WIDGET_TYPE);
   assertEquals(button.getClass().getName(), type);
   JSONArray styles = payload.getJSONArray(IProtocolConstants.KEY_WIDGET_STYLE);
   assertEquals("PUSH", styles.getString(0));
   assertEquals("BORDER", styles.getString(1));
 }
  /**
   * Executes the request and returns PluginResult.
   *
   * @param action The action to execute.
   * @param args JSONArry of arguments for the plugin.
   * @param callbackId 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 {
    try {
      if (action.equals("open")) {
        this.callbackContext = callbackContext;
        String url = args.getString(0);
        String target = args.optString(1);
        if (target == null || target.equals("") || target.equals(NULL)) {
          target = SELF;
        }
        HashMap<String, Boolean> features = parseFeature(args.optString(2));

        Log.d(LOG_TAG, "target = " + target);

        url = updateUrl(url);
        String result = "";

        // SELF
        if (SELF.equals(target)) {
          Log.d(LOG_TAG, "in self");
          // load in webview
          if (url.startsWith("file://")
              || url.startsWith("javascript:")
              || Config.isUrlWhiteListed(url)) {
            this.webView.loadUrl(url);
          }
          // Load the dialer
          else if (url.startsWith(WebView.SCHEME_TEL)) {
            try {
              Intent intent = new Intent(Intent.ACTION_DIAL);
              intent.setData(Uri.parse(url));
              this.cordova.getActivity().startActivity(intent);
            } catch (android.content.ActivityNotFoundException e) {
              LOG.e(LOG_TAG, "Error dialing " + url + ": " + e.toString());
            }
          }
          // load in InAppBrowser
          else {
            result = this.showWebPage(url, features);
          }
        }
        // SYSTEM
        else if (SYSTEM.equals(target)) {
          Log.d(LOG_TAG, "in system");
          result = this.openExternal(url);
        }
        // BLANK - or anything else
        else {
          Log.d(LOG_TAG, "in blank");
          result = this.showWebPage(url, features);
        }

        PluginResult pluginResult = new PluginResult(PluginResult.Status.OK, result);
        pluginResult.setKeepCallback(true);
        this.callbackContext.sendPluginResult(pluginResult);
      } else if (action.equals("close")) {
        closeDialog();
        this.callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK));
      } else if (action.equals("injectScriptCode")) {
        String jsWrapper = null;
        if (args.getBoolean(1)) {
          jsWrapper =
              String.format(
                  "prompt(JSON.stringify([eval(%%s)]), 'gap-iab://%s')",
                  callbackContext.getCallbackId());
        }
        injectDeferredObject(args.getString(0), jsWrapper);
      } else if (action.equals("injectScriptFile")) {
        String jsWrapper;
        if (args.getBoolean(1)) {
          jsWrapper =
              String.format(
                  "(function(d) { var c = d.createElement('script'); c.src = %%s; c.onload = function() { prompt('', 'gap-iab://%s'); }; d.body.appendChild(c); })(document)",
                  callbackContext.getCallbackId());
        } else {
          jsWrapper =
              "(function(d) { var c = d.createElement('script'); c.src = %s; d.body.appendChild(c); })(document)";
        }
        injectDeferredObject(args.getString(0), jsWrapper);
      } else if (action.equals("injectStyleCode")) {
        String jsWrapper;
        if (args.getBoolean(1)) {
          jsWrapper =
              String.format(
                  "(function(d) { var c = d.createElement('style'); c.innerHTML = %%s; d.body.appendChild(c); prompt('', 'gap-iab://%s');})(document)",
                  callbackContext.getCallbackId());
        } else {
          jsWrapper =
              "(function(d) { var c = d.createElement('style'); c.innerHTML = %s; d.body.appendChild(c); })(document)";
        }
        injectDeferredObject(args.getString(0), jsWrapper);
      } else if (action.equals("injectStyleFile")) {
        String jsWrapper;
        if (args.getBoolean(1)) {
          jsWrapper =
              String.format(
                  "(function(d) { var c = d.createElement('link'); c.rel='stylesheet'; c.type='text/css'; c.href = %%s; d.head.appendChild(c); prompt('', 'gap-iab://%s');})(document)",
                  callbackContext.getCallbackId());
        } else {
          jsWrapper =
              "(function(d) { var c = d.createElement('link'); c.rel='stylesheet'; c.type='text/css'; c.href = %s; d.head.appendChild(c); })(document)";
        }
        injectDeferredObject(args.getString(0), jsWrapper);
      } else if (action.equals("show")) {
        Runnable runnable =
            new Runnable() {
              @Override
              public void run() {
                dialog.show();
              }
            };
        this.cordova.getActivity().runOnUiThread(runnable);
        this.callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK));
      } else {
        return false;
      }
    } catch (JSONException e) {
      this.callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
    }
    return true;
  }
 @Override
 public boolean execute(String action, JSONArray args, CallbackContext callbackContext)
     throws JSONException {
   if (START_TRACKER.equals(action)) {
     String id = args.getString(0);
     this.startTracker(id, callbackContext);
     return true;
   } else if (TRACK_VIEW.equals(action)) {
     String screen = args.getString(0);
     this.trackView(screen, callbackContext);
     return true;
   } else if (TRACK_EVENT.equals(action)) {
     int length = args.length();
     if (length > 0) {
       this.trackEvent(
           args.getString(0),
           length > 1 ? args.getString(1) : "",
           length > 2 ? args.getString(2) : "",
           length > 3 ? args.getLong(3) : 0,
           callbackContext);
     }
     return true;
   } else if (TRACK_EXCEPTION.equals(action)) {
     String description = args.getString(0);
     Boolean fatal = args.getBoolean(1);
     this.trackException(description, fatal, callbackContext);
     return true;
   } else if (TRACK_TIMING.equals(action)) {
     int length = args.length();
     if (length > 0) {
       this.trackTiming(
           args.getString(0),
           length > 1 ? args.getLong(1) : 0,
           length > 2 ? args.getString(2) : "",
           length > 3 ? args.getString(3) : "",
           callbackContext);
     }
     return true;
   } else if (ADD_DIMENSION.equals(action)) {
     Integer key = args.getInt(0);
     String value = args.getString(1);
     this.addCustomDimension(key, value, callbackContext);
     return true;
   } else if (ADD_TRANSACTION.equals(action)) {
     int length = args.length();
     if (length > 0) {
       this.addTransaction(
           args.getString(0),
           length > 1 ? args.getString(1) : "",
           length > 2 ? args.getDouble(2) : 0,
           length > 3 ? args.getDouble(3) : 0,
           length > 4 ? args.getDouble(4) : 0,
           length > 5 ? args.getString(5) : null,
           callbackContext);
     }
     return true;
   } else if (ADD_TRANSACTION_ITEM.equals(action)) {
     int length = args.length();
     if (length > 0) {
       this.addTransactionItem(
           args.getString(0),
           length > 1 ? args.getString(1) : "",
           length > 2 ? args.getString(2) : "",
           length > 3 ? args.getString(3) : "",
           length > 4 ? args.getDouble(4) : 0,
           length > 5 ? args.getLong(5) : 0,
           length > 6 ? args.getString(6) : null,
           callbackContext);
     }
     return true;
   } else if (SET_USER_ID.equals(action)) {
     String userId = args.getString(0);
     this.setUserId(userId, callbackContext);
   } else if (DEBUG_MODE.equals(action)) {
     this.debugMode(callbackContext);
   } else if (ENABLE_UNCAUGHT_EXCEPTION_REPORTING.equals(action)) {
     Boolean enable = args.getBoolean(0);
     this.enableUncaughtExceptionReporting(enable, callbackContext);
   } else if (ENABLE_ADVERTISING_ID_COLLECTION.equals(action)) {
     this.enableAdvertisingIdCollection(callbackContext);
   }
   return false;
 }
 @Override
 public boolean execute(String action, JSONArray args, CallbackContext callbackContext)
     throws JSONException {
   if (START_TRACKER.equals(action)) {
     String id = args.getString(0);
     this.startTracker(id, callbackContext);
     return true;
   } else if (TRACK_VIEW.equals(action)) {
     String screen = args.getString(0);
     String deepLinkUrl = args.optString(1);
     this.trackView(screen, deepLinkUrl, callbackContext);
     return true;
   } else if (TRACK_EVENT.equals(action)) {
     int length = args.length();
     if (length > 0) {
       this.trackEvent(
           args.getString(0),
           length > 1 ? args.getString(1) : "",
           length > 2 ? args.getString(2) : "",
           length > 3 ? args.getString(3) : "",
           length > 4 ? args.getLong(4) : 0,
           callbackContext);
     }
     return true;
   } else if (TRACK_EXCEPTION.equals(action)) {
     String description = args.getString(0);
     Boolean fatal = args.getBoolean(1);
     this.trackException(description, fatal, callbackContext);
     return true;
   } else if (TRACK_TIMING.equals(action)) {
     int length = args.length();
     if (length > 0) {
       this.trackTiming(
           args.getString(0),
           length > 1 ? args.getLong(1) : 0,
           length > 2 ? args.getString(2) : "",
           length > 3 ? args.getString(3) : "",
           callbackContext);
     }
     return true;
   } else if (ADD_CUSTOM_METRIC.equals(action)) {
     String key = args.getString(0);
     String value = args.getString(1);
     this.addCustomMetric(key, value, callbackContext);
     return true;
   } else if (ADD_DIMENSION.equals(action)) {
     String key = args.getString(0);
     String value = args.getString(1);
     this.addCustomDimension(key, value, callbackContext);
     return true;
   } else if (ADD_TRANSACTION.equals(action)) {
     int length = args.length();
     if (length > 0) {
       this.addTransaction(
           args.getString(0),
           length > 1 ? args.getString(1) : "",
           length > 2 ? args.getDouble(2) : 0,
           length > 3 ? args.getDouble(3) : 0,
           length > 4 ? args.getDouble(4) : 0,
           length > 5 ? args.getString(5) : null,
           callbackContext);
     }
     return true;
   } else if (ADD_TRANSACTION_ITEM.equals(action)) {
     int length = args.length();
     if (length > 0) {
       this.addTransactionItem(
           args.getString(0),
           length > 1 ? args.getString(1) : "",
           length > 2 ? args.getString(2) : "",
           length > 3 ? args.getString(3) : "",
           length > 4 ? args.getDouble(4) : 0,
           length > 5 ? args.getLong(5) : 0,
           length > 6 ? args.getString(6) : null,
           callbackContext);
     }
     return true;
   } else if (SET_USER_ID.equals(action)) {
     String userId = args.getString(0);
     this.setUserId(userId, callbackContext);
   } else if (DEBUG_MODE.equals(action)) {
     this.debugMode(callbackContext);
   } else if (ALLOW_IDFA_COLLECTION.equals(action)) {
     callbackContext.success("Don't need to enable IDFA for android");
     return true;
   }
   return false;
 }
 /**
  * Set visibility for the object
  *
  * @param args
  * @param callbackContext
  * @throws JSONException
  */
 @SuppressWarnings("unused")
 private void setVisible(JSONArray args, CallbackContext callbackContext) throws JSONException {
   boolean visible = args.getBoolean(2);
   String id = args.getString(1);
   this.setBoolean("setVisible", id, visible, callbackContext);
 }
  @Override
  public boolean execute(String action, JSONArray data, CallbackContext callbackId) {
    Log.d("PushNotifications", "Plugin Called");

    // make sure the receivers are on
    registerReceivers();

    if (ON_DEVICE_READY.equals(action)) {
      checkMessage(cordova.getActivity().getIntent());
      return true;
    }

    if (REGISTER.equals(action)) {
      return internalRegister(data, callbackId);
    }

    if (UNREGISTER.equals(action)) {
      return internalUnregister(data, callbackId);
    }

    if (SET_TAGS.equals(action)) {
      return internalSendTags(data, callbackId);
    }

    if (SEND_LOCATION.equals(action)) {
      return internalSendLocation(data, callbackId);
    }

    if (START_GEO_PUSHES.equals(action)) {
      if (mPushManager == null) {
        return false;
      }

      mPushManager.startTrackingGeoPushes();
      return true;
    }

    if (STOP_GEO_PUSHES.equals(action)) {
      if (mPushManager == null) {
        return false;
      }

      mPushManager.stopTrackingGeoPushes();
      return true;
    }

    if (CREATE_LOCAL_NOTIFICATION.equals(action)) {
      JSONObject params = null;
      try {
        params = data.getJSONObject(0);
      } catch (JSONException e) {
        e.printStackTrace();
        return false;
      }

      try {
        // config params: {msg:"message", seconds:30, userData:"optional"}
        String message = params.getString("msg");
        Integer seconds = params.getInt("seconds");
        if (message == null || seconds == null) return false;

        String userData = params.getString("userData");

        Bundle extras = new Bundle();
        if (userData != null) extras.putString("u", userData);

        PushManager.scheduleLocalNotification(cordova.getActivity(), message, extras, seconds);
      } catch (JSONException e) {
        e.printStackTrace();
        return false;
      }

      return true;
    }

    if (CLEAR_LOCAL_NOTIFICATION.equals(action)) {
      PushManager.clearLocalNotifications(cordova.getActivity());
      return true;
    }

    if ("setMultiNotificationMode".equals(action)) {
      PushManager.setMultiNotificationMode(cordova.getActivity());
      return true;
    }

    if ("setSingleNotificationMode".equals(action)) {
      PushManager.setSimpleNotificationMode(cordova.getActivity());
      return true;
    }

    if ("setSoundType".equals(action)) {
      try {
        Integer type = (Integer) data.get(0);
        if (type == null) return false;

        PushManager.setSoundNotificationType(cordova.getActivity(), SoundType.fromInt(type));
      } catch (Exception e) {
        e.printStackTrace();
        return false;
      }

      return true;
    }

    if ("setVibrateType".equals(action)) {
      try {
        Integer type = (Integer) data.get(0);
        if (type == null) return false;

        PushManager.setVibrateNotificationType(cordova.getActivity(), VibrateType.fromInt(type));
      } catch (Exception e) {
        e.printStackTrace();
        return false;
      }

      return true;
    }

    if ("setLightScreenOnNotification".equals(action)) {
      try {
        boolean type = (boolean) data.getBoolean(0);
        PushManager.setLightScreenOnNotification(cordova.getActivity(), type);
      } catch (Exception e) {
        e.printStackTrace();
        return false;
      }

      return true;
    }

    if ("setEnableLED".equals(action)) {
      try {
        boolean type = (boolean) data.getBoolean(0);
        PushManager.setEnableLED(cordova.getActivity(), type);
      } catch (Exception e) {
        e.printStackTrace();
        return false;
      }

      return true;
    }

    if ("sendGoalAchieved".equals(action)) {
      JSONObject params = null;
      try {
        params = data.getJSONObject(0);
      } catch (JSONException e) {
        e.printStackTrace();
        return false;
      }

      try {
        // config params: {goal:"goalName", count:30}
        String goal = params.getString("goal");
        if (goal == null) return false;

        Integer count = null;
        if (params.has("count")) count = params.getInt("count");

        PushManager.sendGoalAchieved(cordova.getActivity(), goal, count);
      } catch (Exception e) {
        e.printStackTrace();
        return false;
      }

      return true;
    }

    Log.d("DirectoryListPlugin", "Invalid action : " + action + " passed");
    return false;
  }
  /**
   * Tell the client to display a prompt dialog to the user. If the client returns true, WebView
   * will assume that the client will handle the prompt dialog and call the appropriate
   * JsPromptResult method.
   *
   * <p>Since we are hacking prompts for our own purposes, we should not be using them for this
   * purpose, perhaps we should hack console.log to do this instead!
   *
   * @param view
   * @param url
   * @param message
   * @param defaultValue
   * @param result
   */
  @Override
  public boolean onJsPrompt(
      WebView view, String url, String message, String defaultValue, JsPromptResult result) {

    // Security check to make sure any requests are coming from the page initially
    // loaded in webview and not another loaded in an iframe.
    boolean reqOk = false;
    if (url.startsWith("file://")
        || url.indexOf(this.ctx.baseUrl) == 0
        || ctx.isUrlWhiteListed(url)) {
      reqOk = true;
    }

    // Calling PluginManager.exec() to call a native service using
    // prompt(this.stringify(args), "gap:"+this.stringify([service, action, callbackId, true]));
    if (reqOk
        && defaultValue != null
        && defaultValue.length() > 3
        && defaultValue.substring(0, 4).equals("gap:")) {
      JSONArray array;
      try {
        array = new JSONArray(defaultValue.substring(4));
        String service = array.getString(0);
        String action = array.getString(1);
        String callbackId = array.getString(2);
        boolean async = array.getBoolean(3);
        String r = ctx.pluginManager.exec(service, action, callbackId, message, async);
        result.confirm(r);
      } catch (JSONException e) {
        e.printStackTrace();
      }
    }

    // Polling for JavaScript messages
    else if (reqOk && defaultValue != null && defaultValue.equals("gap_poll:")) {
      String r = ctx.callbackServer.getJavascript();
      result.confirm(r);
    }

    // Calling into CallbackServer
    else if (reqOk && defaultValue != null && defaultValue.equals("gap_callbackServer:")) {
      String r = "";
      if (message.equals("usePolling")) {
        r = "" + ctx.callbackServer.usePolling();
      } else if (message.equals("restartServer")) {
        ctx.callbackServer.restartServer();
      } else if (message.equals("getPort")) {
        r = Integer.toString(ctx.callbackServer.getPort());
      } else if (message.equals("getToken")) {
        r = ctx.callbackServer.getToken();
      }
      result.confirm(r);
    }

    // Cordova JS has initialized, so show webview
    // (This solves white flash seen when rendering HTML)
    else if (reqOk && defaultValue != null && defaultValue.equals("gap_init:")) {
      ctx.appView.setVisibility(View.VISIBLE);
      ctx.spinnerStop();
      result.confirm("OK");
    }

    // Show dialog
    else {
      final JsPromptResult res = result;
      AlertDialog.Builder dlg = new AlertDialog.Builder(this.ctx);
      dlg.setMessage(message);
      final EditText input = new EditText(this.ctx);
      if (defaultValue != null) {
        input.setText(defaultValue);
      }
      dlg.setView(input);
      dlg.setCancelable(false);
      dlg.setPositiveButton(
          android.R.string.ok,
          new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
              String usertext = input.getText().toString();
              res.confirm(usertext);
            }
          });
      dlg.setNegativeButton(
          android.R.string.cancel,
          new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
              res.cancel();
            }
          });
      dlg.create();
      dlg.show();
    }
    return true;
  }
  @Override
  public boolean execute(String action, JSONArray args, final CallbackContext callbackContext)
      throws JSONException {

    this.cordova.setActivityResultCallback(this);
    this.callbackContext = callbackContext;

    if (action.equals("createAsync")) {

      // Don't catch JSONException since it is already handled by Cordova
      String authority = args.getString(0);
      // Due to
      // https://github.com/AzureAD/azure-activedirectory-library-for-android/blob/master/src/src/com/microsoft/aad/adal/AuthenticationContext.java#L158
      // AuthenticationContext constructor validates authority by default
      boolean validateAuthority = args.optBoolean(1, true);
      return createAsync(authority, validateAuthority);

    } else if (action.equals("acquireTokenAsync")) {

      String authority = args.getString(0);
      String resourceUrl = args.getString(1);
      String clientId = args.getString(2);
      String redirectUrl = args.getString(3);
      String userId = args.optString(4, null);
      userId = userId.equals("null") ? null : userId;
      String extraQueryParams = args.optString(5, null);
      extraQueryParams = extraQueryParams.equals("null") ? null : extraQueryParams;

      return acquireTokenAsync(
          authority, resourceUrl, clientId, redirectUrl, userId, extraQueryParams);

    } else if (action.equals("acquireTokenSilentAsync")) {

      String authority = args.getString(0);
      String resourceUrl = args.getString(1);
      String clientId = args.getString(2);
      String userId = args.getString(3);

      // This is a workaround for Cordova bridge issue. When null us passed from JS side
      // it is being translated to "null" string
      userId = userId.equals("null") ? null : userId;

      return acquireTokenSilentAsync(authority, resourceUrl, clientId, userId);

    } else if (action.equals("tokenCacheClear")) {

      String authority = args.getString(0);
      return clearTokenCache(authority);

    } else if (action.equals("tokenCacheReadItems")) {

      String authority = args.getString(0);
      return readTokenCacheItems(authority);

    } else if (action.equals("tokenCacheDeleteItem")) {

      String authority = args.getString(0);
      String itemAuthority = args.getString(1);
      String resource = args.getString(2);
      resource = resource.equals("null") ? null : resource;
      String clientId = args.getString(3);
      String userId = args.getString(4);
      boolean isMultipleResourceRefreshToken = args.getBoolean(5);

      return deleteTokenCacheItem(
          authority, itemAuthority, resource, clientId, userId, isMultipleResourceRefreshToken);
    }

    return false;
  }
 public boolean getBoolean(int index) throws JSONException {
   return baseArgs.getBoolean(index);
 }
 public void testMessageWithConstruct() throws IOException, JSONException {
   StringWriter stringWriter = new StringWriter();
   PrintWriter printWriter = new PrintWriter(stringWriter);
   ProtocolMessageWriter writer = new JsonMessageWriter(printWriter);
   Display display = new Display();
   Shell shell = new Shell(display);
   Button button = new Button(shell, SWT.PUSH);
   writer.addConstructPayload(
       WidgetUtil.getId(shell),
       DisplayUtil.getId(display),
       "org.Text",
       new String[] {"TRIM"},
       new Object[] {"a", "b"});
   String parentId = "";
   if (shell.getParent() != null) {
     parentId = WidgetUtil.getId(shell.getParent());
   } else {
     parentId = DisplayUtil.getId(display);
   }
   String widgetId = WidgetUtil.getId(shell);
   String actual = stringWriter.getBuffer().toString();
   JSONObject message = new JSONObject(actual + "]}");
   JSONArray widgetArray = message.getJSONArray(IProtocolConstants.MESSAGE_WIDGETS);
   JSONObject widgetObject = widgetArray.getJSONObject(0);
   String type = widgetObject.getString(IProtocolConstants.WIDGETS_TYPE);
   assertEquals(IProtocolConstants.PAYLOAD_CONSTRUCT, type);
   String actualId = widgetObject.getString(IProtocolConstants.WIDGETS_ID);
   assertEquals(widgetId, actualId);
   JSONObject payload = widgetObject.getJSONObject(IProtocolConstants.WIDGETS_PAYLOAD);
   String actualParentId = payload.getString(IProtocolConstants.KEY_PARENT_ID);
   assertEquals(parentId, actualParentId);
   String actualType = payload.getString(IProtocolConstants.KEY_WIDGET_TYPE);
   assertEquals("org.Text", actualType);
   JSONArray actualStyle = payload.getJSONArray(IProtocolConstants.KEY_WIDGET_STYLE);
   assertEquals("TRIM", actualStyle.getString(0));
   JSONArray actualParams = payload.getJSONArray(IProtocolConstants.KEY_PARAMETER_LIST);
   assertEquals("a", actualParams.getString(0));
   assertEquals("b", actualParams.getString(1));
   writer.addConstructPayload(
       WidgetUtil.getId(button),
       WidgetUtil.getId(shell),
       "org.Shell",
       new String[] {"PUSH", "BORDER"},
       new Object[] {"a", new Boolean(true)});
   writer.finish();
   actual = stringWriter.getBuffer().toString();
   message = new JSONObject(actual);
   widgetArray = message.getJSONArray(IProtocolConstants.MESSAGE_WIDGETS);
   widgetObject = widgetArray.getJSONObject(1);
   type = widgetObject.getString(IProtocolConstants.WIDGETS_TYPE);
   assertEquals(IProtocolConstants.PAYLOAD_CONSTRUCT, type);
   actualId = widgetObject.getString(IProtocolConstants.WIDGETS_ID);
   assertEquals(WidgetUtil.getId(button), actualId);
   payload = widgetObject.getJSONObject(IProtocolConstants.WIDGETS_PAYLOAD);
   JSONArray styles = payload.getJSONArray(IProtocolConstants.KEY_WIDGET_STYLE);
   assertEquals("PUSH", styles.getString(0));
   assertEquals("BORDER", styles.getString(1));
   String actualParent = payload.getString(IProtocolConstants.KEY_PARENT_ID);
   assertEquals(WidgetUtil.getId(shell), actualParent);
   JSONArray params = payload.getJSONArray(IProtocolConstants.KEY_PARAMETER_LIST);
   assertTrue(params.getBoolean(1));
 }
  // get json array object at index with object class name
  private static Object getJSONArrayObject(
      JSONArray jsonArray, int index, Class<? extends Object> objectClass) {
    Object _object = null;

    // check json array
    if (null != jsonArray) {
      // check json array bounds
      if (index < jsonArray.length()) {
        try {
          if (Integer.class == objectClass) {
            _object = jsonArray.getInt(index);
          } else if (Long.class == objectClass) {
            _object = jsonArray.getLong(index);
          } else if (Double.class == objectClass) {
            _object = jsonArray.getDouble(index);
          } else if (Boolean.class == objectClass) {
            _object = jsonArray.getBoolean(index);
          } else if (String.class == objectClass) {
            _object = jsonArray.getString(index);
          } else if (JSONObject.class == objectClass) {
            _object = jsonArray.getJSONObject(index);
          } else if (JSONArray.class == objectClass) {
            _object = jsonArray.getJSONArray(index);
          } else {
            _object = jsonArray.get(index);
          }
        } catch (JSONException e) {
          Log.e(
              LOG_TAG,
              "Get json array = "
                  + jsonArray
                  + " object at index = "
                  + index
                  + " and object class = "
                  + objectClass.getName()
                  + " exception message = "
                  + e.getMessage());

          e.printStackTrace();
        }
      } else {
        Log.e(
            LOG_TAG,
            "Get json array object at index = "
                + index
                + " and object class = "
                + objectClass.getName()
                + ", index out of json array bounds");
      }
    } else {
      Log.e(
          LOG_TAG,
          "Get json array object at index = "
              + index
              + " and object class = "
              + objectClass.getName()
              + ", json array is null");
    }

    return _object;
  }
  private void deserializeKey(String key, Bundle bundle) throws JSONException {
    String jsonString = cache.getString(key, "{}");
    JSONObject json = new JSONObject(jsonString);

    String valueType = json.getString(JSON_VALUE_TYPE);

    if (valueType.equals(TYPE_BOOLEAN)) {
      bundle.putBoolean(key, json.getBoolean(JSON_VALUE));
    } else if (valueType.equals(TYPE_BOOLEAN_ARRAY)) {
      JSONArray jsonArray = json.getJSONArray(JSON_VALUE);
      boolean[] array = new boolean[jsonArray.length()];
      for (int i = 0; i < array.length; i++) {
        array[i] = jsonArray.getBoolean(i);
      }
      bundle.putBooleanArray(key, array);
    } else if (valueType.equals(TYPE_BYTE)) {
      bundle.putByte(key, (byte) json.getInt(JSON_VALUE));
    } else if (valueType.equals(TYPE_BYTE_ARRAY)) {
      JSONArray jsonArray = json.getJSONArray(JSON_VALUE);
      byte[] array = new byte[jsonArray.length()];
      for (int i = 0; i < array.length; i++) {
        array[i] = (byte) jsonArray.getInt(i);
      }
      bundle.putByteArray(key, array);
    } else if (valueType.equals(TYPE_SHORT)) {
      bundle.putShort(key, (short) json.getInt(JSON_VALUE));
    } else if (valueType.equals(TYPE_SHORT_ARRAY)) {
      JSONArray jsonArray = json.getJSONArray(JSON_VALUE);
      short[] array = new short[jsonArray.length()];
      for (int i = 0; i < array.length; i++) {
        array[i] = (short) jsonArray.getInt(i);
      }
      bundle.putShortArray(key, array);
    } else if (valueType.equals(TYPE_INTEGER)) {
      bundle.putInt(key, json.getInt(JSON_VALUE));
    } else if (valueType.equals(TYPE_INTEGER_ARRAY)) {
      JSONArray jsonArray = json.getJSONArray(JSON_VALUE);
      int[] array = new int[jsonArray.length()];
      for (int i = 0; i < array.length; i++) {
        array[i] = jsonArray.getInt(i);
      }
      bundle.putIntArray(key, array);
    } else if (valueType.equals(TYPE_LONG)) {
      bundle.putLong(key, json.getLong(JSON_VALUE));
    } else if (valueType.equals(TYPE_LONG_ARRAY)) {
      JSONArray jsonArray = json.getJSONArray(JSON_VALUE);
      long[] array = new long[jsonArray.length()];
      for (int i = 0; i < array.length; i++) {
        array[i] = jsonArray.getLong(i);
      }
      bundle.putLongArray(key, array);
    } else if (valueType.equals(TYPE_FLOAT)) {
      bundle.putFloat(key, (float) json.getDouble(JSON_VALUE));
    } else if (valueType.equals(TYPE_FLOAT_ARRAY)) {
      JSONArray jsonArray = json.getJSONArray(JSON_VALUE);
      float[] array = new float[jsonArray.length()];
      for (int i = 0; i < array.length; i++) {
        array[i] = (float) jsonArray.getDouble(i);
      }
      bundle.putFloatArray(key, array);
    } else if (valueType.equals(TYPE_DOUBLE)) {
      bundle.putDouble(key, json.getDouble(JSON_VALUE));
    } else if (valueType.equals(TYPE_DOUBLE_ARRAY)) {
      JSONArray jsonArray = json.getJSONArray(JSON_VALUE);
      double[] array = new double[jsonArray.length()];
      for (int i = 0; i < array.length; i++) {
        array[i] = jsonArray.getDouble(i);
      }
      bundle.putDoubleArray(key, array);
    } else if (valueType.equals(TYPE_CHAR)) {
      String charString = json.getString(JSON_VALUE);
      if (charString != null && charString.length() == 1) {
        bundle.putChar(key, charString.charAt(0));
      }
    } else if (valueType.equals(TYPE_CHAR_ARRAY)) {
      JSONArray jsonArray = json.getJSONArray(JSON_VALUE);
      char[] array = new char[jsonArray.length()];
      for (int i = 0; i < array.length; i++) {
        String charString = jsonArray.getString(i);
        if (charString != null && charString.length() == 1) {
          array[i] = charString.charAt(0);
        }
      }
      bundle.putCharArray(key, array);
    } else if (valueType.equals(TYPE_STRING)) {
      bundle.putString(key, json.getString(JSON_VALUE));
    } else if (valueType.equals(TYPE_STRING_LIST)) {
      JSONArray jsonArray = json.getJSONArray(JSON_VALUE);
      int numStrings = jsonArray.length();
      ArrayList<String> stringList = new ArrayList<String>(numStrings);
      for (int i = 0; i < numStrings; i++) {
        Object jsonStringValue = jsonArray.get(i);
        stringList.add(i, jsonStringValue == JSONObject.NULL ? null : (String) jsonStringValue);
      }
      bundle.putStringArrayList(key, stringList);
    } else if (valueType.equals(TYPE_ENUM)) {
      try {
        String enumType = json.getString(JSON_VALUE_ENUM_TYPE);
        @SuppressWarnings({"unchecked", "rawtypes"})
        Class<? extends Enum> enumClass = (Class<? extends Enum>) Class.forName(enumType);
        @SuppressWarnings("unchecked")
        Enum<?> enumValue = Enum.valueOf(enumClass, json.getString(JSON_VALUE));
        bundle.putSerializable(key, enumValue);
      } catch (ClassNotFoundException e) {
      } catch (IllegalArgumentException e) {
      }
    }
  }
  @Override
  public boolean execute(String action, JSONArray args, final CallbackContext callbackContext)
      throws JSONException {
    mFolderName = args.isNull(10) ? mFolderName : args.getString(10);
    mGalleryFolder = createFolders();

    if (action.equals("show")) {
      try {
        Log.i(LOG_TAG, action);
        this.callbackContext = callbackContext;

        // make sure an image URI has been provided
        if (args.isNull(0)) {
          callbackContext.error("Cannot start aviary, an image URI is required.");
          return true;
        }

        // parameters
        String source = args.getString(0); // 0 - image URI
        String outputFormat =
            args.isNull(1)
                ? Bitmap.CompressFormat.JPEG.name()
                : args.getString(1); // 1 - EXTRA_OUTPUT_FORMAT
        int quality = args.isNull(2) ? 95 : args.getInt(2); // 2 - EXTRA_OUTPUT_QUALITY

        String[] toolList = new String[] {}; // 3 - EXTRA_TOOLS_LIST
        if (!args.isNull(3)) {
          JSONArray toolArray = args.getJSONArray(3);
          toolList = new String[toolArray.length()];
          for (int i = 0; i < toolArray.length(); i++) {
            toolList[i] = toolArray.getString(i);
          }
        }

        Boolean hideExitUnsaveConfirmation =
            args.isNull(4) ? false : args.getBoolean(4); // 4 - EXTRA_HIDE_EXIT_UNSAVE_CONFIRMATION
        Boolean enableEffectsPacks =
            args.isNull(5) ? false : args.getBoolean(5); // 5 - EXTRA_EFFECTS_ENABLE_EXTERNAL_PACKS
        Boolean enableFramesPacks =
            args.isNull(6) ? false : args.getBoolean(6); // 6 - EXTRA_FRAMES_ENABLE_EXTERNAL_PACKS
        Boolean enableStickersPacks =
            args.isNull(7) ? false : args.getBoolean(7); // 7 - EXTRA_STICKERS_ENABLE_EXTERNAL_PACKS
        Boolean disableVibration =
            args.isNull(8) ? false : args.getBoolean(8); // 8 - EXTRA_TOOLS_DISABLE_VIBRATION
        Boolean inSaveOnNoChanges =
            args.isNull(9) ? true : args.getBoolean(9); // 9 - EXTRA_IN_SAVE_ON_NO_CHANGES

        // get URI
        Uri uri = Uri.parse(source);

        // first check the external storage availability
        if (!isExternalStorageAvilable()) {
          callbackContext.error("Cannot start aviary, external storage unavailable.");
          return true;
        }
        String mOutputFilePath;

        // create a temporary file where to store the resulting image
        File file = getNextFileName();
        if (null != file) {
          mOutputFilePath = file.getAbsolutePath();
        } else {
          callbackContext.error("Cannot start aviary, failed to create a temp file.");
          return true;
        }

        // Create the intent needed to start feather
        Class<FeatherActivity> clsAviary = FeatherActivity.class;
        Intent newIntent = new Intent(this.cordova.getActivity(), clsAviary);

        // set the parameters
        newIntent.setData(uri);
        newIntent.putExtra(Constants.EXTRA_OUTPUT, Uri.parse("file://" + mOutputFilePath));
        newIntent.putExtra(Constants.EXTRA_OUTPUT_FORMAT, outputFormat);
        newIntent.putExtra(Constants.EXTRA_OUTPUT_QUALITY, quality);

        if (toolList.length > 0) {
          newIntent.putExtra(Constants.EXTRA_TOOLS_LIST, toolList);
        }

        newIntent.putExtra(
            Constants.EXTRA_HIDE_EXIT_UNSAVE_CONFIRMATION, hideExitUnsaveConfirmation);

        newIntent.putExtra(Constants.EXTRA_EFFECTS_ENABLE_EXTERNAL_PACKS, enableEffectsPacks);
        newIntent.putExtra(Constants.EXTRA_FRAMES_ENABLE_EXTERNAL_PACKS, enableFramesPacks);
        newIntent.putExtra(Constants.EXTRA_STICKERS_ENABLE_EXTERNAL_PACKS, enableStickersPacks);

        // http://developers.aviary.com/docs/android/intent-parameters#EXTRA_MAX_IMAGE_SIZE
        // newIntent.putExtra(Constants.EXTRA_MAX_IMAGE_SIZE, 1000);

        // since a minor bug exists that when explicitly setting this to false disables vibration so
        // only set if true
        if (disableVibration) {
          newIntent.putExtra(Constants.EXTRA_TOOLS_DISABLE_VIBRATION, disableVibration);
        }

        newIntent.putExtra(Constants.EXTRA_IN_SAVE_ON_NO_CHANGES, inSaveOnNoChanges);

        cordova.getActivity().startActivityForResult(newIntent, ACTION_REQUEST_FEATHER);
        cordova.setActivityResultCallback(this);
        return true;
      } catch (Exception ex) {
        Log.e(LOG_TAG, ex.toString());
        callbackContext.error("Unknown error occured showing aviary.");
      }
    } else if (action.equals("prepareForShow")) {
      // nothing to do on Android
      callbackContext.success();
    }

    return false;
  }
 @Override
 public void call(JSONArray args) throws JSONException {
   Crashlytics.setBool(args.getString(0), args.getBoolean(1));
 }