/**
  * Create a new plugin result and send it back to JavaScript
  *
  * @param obj a JSONObject contain event payload information
  */
 private void sendUpdate(JSONObject obj, boolean keepCallback) {
   if (this.browserCallbackId != null) {
     PluginResult result = new PluginResult(PluginResult.Status.OK, obj);
     result.setKeepCallback(keepCallback);
     this.success(result, this.browserCallbackId);
   }
 }
  @Override
  public void onReceive(Context ctx, Intent intent) {

    // Get the SMS map from Intent
    Bundle extras = intent.getExtras();
    if (extras != null) {
      // Get received SMS Array
      Object[] smsExtra = (Object[]) extras.get(SMS_EXTRA_NAME);

      for (int i = 0; i < smsExtra.length; i++) {
        SmsMessage sms = SmsMessage.createFromPdu((byte[]) smsExtra[i]);
        if (this.isReceiving && this.callback_receive != null) {
          String formattedMsg = sms.getOriginatingAddress() + ">" + sms.getMessageBody();
          PluginResult result = new PluginResult(PluginResult.Status.OK, formattedMsg);
          result.setKeepCallback(true);
          callback_receive.sendPluginResult(result);
        }
      }

      // If the plugin is active and we don't want to broadcast to other receivers
      if (this.isReceiving && !broadcast) {
        this.abortBroadcast();
      }
    }
  }
  /**
   * Executes the request and returns PluginResult.
   *
   * @param action The action to execute.
   * @param args JSONArray 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.
   */
  @Override
  public PluginResult execute(String action, JSONArray args, String callbackId) {
    this.callback = callbackId;

    if (action.equals("encode")) {
      JSONObject obj = args.optJSONObject(0);
      if (obj != null) {
        String type = obj.optString("type");
        String data = obj.optString("data");

        // If the type is null then force the type to text
        if (type == null) {
          type = TEXT_TYPE;
        }

        if (data == null) {
          return new PluginResult(PluginResult.Status.ERROR, "User did not specify data to encode");
        }

        encode(type, data);
      } else {
        return new PluginResult(PluginResult.Status.ERROR, "User did not specify data to encode");
      }
    } else if (action.equals("scan")) {
      scan();
    } else {
      return new PluginResult(PluginResult.Status.INVALID_ACTION);
    }
    PluginResult r = new PluginResult(PluginResult.Status.NO_RESULT);
    r.setKeepCallback(true);
    return r;
  }
  /**
   * Create a new plugin result and send it back to JavaScript
   *
   * @param connection the network info to set as navigator.connection
   */
  private void sendUpdate(String type) {
    if (connectionCallbackContext != null) {
      PluginResult result = new PluginResult(PluginResult.Status.OK, type);
      result.setKeepCallback(true);
      connectionCallbackContext.sendPluginResult(result);
    }

    webView.postMessage("networkconnection", type);
  }
 /**
  * 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 True if the action was valid, false otherwise.
  */
 public boolean execute(String action, JSONArray args, CallbackContext callbackContext) {
   if (action.equals("getConnectionInfo")) {
     this.connectionCallbackContext = callbackContext;
     NetworkInfo info = sockMan.getActiveNetworkInfo();
     PluginResult pluginResult =
         new PluginResult(PluginResult.Status.OK, this.getConnectionInfo(info));
     pluginResult.setKeepCallback(true);
     callbackContext.sendPluginResult(pluginResult);
     return true;
   }
   return false;
 }
  private PluginResult internalUnregister(JSONArray data, String callbackId) {
    callbackIds.put("unregisterDevice", callbackId);
    PluginResult result = new PluginResult(Status.NO_RESULT);
    result.setKeepCallback(true);

    try {
      GCMRegistrar.unregister(cordova.getActivity());
    } catch (Exception e) {
      return new PluginResult(Status.ERROR);
    }

    return result;
  }
  private PluginResult transformResult(ExecuteResult logicResult) {
    PluginResult pluginResult = null;

    Log.d(TAG, "Start of transformResult");
    if (logicResult.getStatus() == ExecuteStatus.OK) {
      Log.d(TAG, "Status is OK");

      if (logicResult.getData() == null) {
        Log.d(TAG, "We dont have data");
        pluginResult = new PluginResult(PluginResult.Status.OK);
      } else {
        Log.d(TAG, "We have data");
        pluginResult = new PluginResult(PluginResult.Status.OK, logicResult.getData());
      }
    }

    if (logicResult.getStatus() == ExecuteStatus.ERROR) {
      Log.d(TAG, "Status is ERROR");

      if (logicResult.getData() == null) {
        Log.d(TAG, "We dont have data");
        pluginResult = new PluginResult(PluginResult.Status.ERROR, "Unknown error");
      } else {
        Log.d(TAG, "We have data");
        pluginResult = new PluginResult(PluginResult.Status.ERROR, logicResult.getData());
      }
    }

    if (logicResult.getStatus() == ExecuteStatus.INVALID_ACTION) {
      Log.d(TAG, "Status is INVALID_ACTION");

      if (logicResult.getData() == null) {
        Log.d(TAG, "We have data");
        pluginResult = new PluginResult(PluginResult.Status.INVALID_ACTION, "Unknown error");
      } else {
        Log.d(TAG, "We dont have data");
        pluginResult = new PluginResult(PluginResult.Status.INVALID_ACTION, logicResult.getData());
      }
    }

    if (!logicResult.isFinished()) {
      Log.d(TAG, "Keep Callback set to true");
      pluginResult.setKeepCallback(true);
    }

    Log.d(TAG, "End of transformResult");
    return pluginResult;
  }
  public PluginResult execute(String action, JSONArray args, String callbackId) {
    if (action.equals("setTabSelectedListener")) {
      this.callback = callbackId;

      if (args.length() != 0) throw new AssertionError("setTabSelectedListener takes no arguments");

      PluginResult res = new PluginResult(PluginResult.Status.NO_RESULT);
      res.setKeepCallback(true);
      return res;
    } else if (action.equals("hide")) {
      final ActionBar actionBar = sherlock.getActionBar();
      cordova
          .getActivity()
          .runOnUiThread(
              new Runnable() {
                @Override
                public void run() {
                  actionBar.hide();
                }
              });
      return new PluginResult(PluginResult.Status.NO_RESULT);
    } else if (action.equals("show")) {
      final ActionBar actionBar = sherlock.getActionBar();
      cordova
          .getActivity()
          .runOnUiThread(
              new Runnable() {
                @Override
                public void run() {
                  actionBar.show();
                }
              });
      return new PluginResult(PluginResult.Status.NO_RESULT);
    } else if (action.equals("_init")) {
      // This is the signal send from the JavaScript that forces construction of this plugin
      if (onInitListener != null) {
        onInitListener.onActionBarSherlockTabBarPluginInitialized();
        onInitListener = null;
      }

      return new PluginResult(PluginResult.Status.NO_RESULT);
    } else {
      Log.e(TAG, "Invalid call: " + action);
      return new PluginResult(PluginResult.Status.INVALID_ACTION);
    }
  }
  private void connect(String url, CallbackContext callbackContext) {

    if (url != null && url.length() > 0) {
      try {
        this.uri = new URI(url);
        this.socketClient = new CordovaClient(uri, callbackContext);
        PluginResult pluginResult = new PluginResult(PluginResult.Status.NO_RESULT);
        pluginResult.setKeepCallback(true);
        callbackContext.sendPluginResult(pluginResult);
        this.socketClient.connect();
      } catch (URISyntaxException e) {
        callbackContext.error("Not a valid URL");
      }
    } else {
      callbackContext.error("Not a valid URL");
    }
  }
  /**
   * 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 PluginResult execute(String action, JSONArray args, String callbackId) {
    PluginResult.Status status = PluginResult.Status.OK;
    String result = "";

    try {
      if (action.equals("showWebPage")) {
        this.browserCallbackId = callbackId;

        // If the ChildBrowser is already open then throw an error
        if (dialog != null && dialog.isShowing()) {
          return new PluginResult(PluginResult.Status.ERROR, "ChildBrowser is already open");
        }

        result = this.showWebPage(args.getString(0), args.optJSONObject(1));

        if (result.length() > 0) {
          status = PluginResult.Status.ERROR;
          return new PluginResult(status, result);
        } else {
          PluginResult pluginResult = new PluginResult(status, result);
          pluginResult.setKeepCallback(true);
          return pluginResult;
        }
      } else if (action.equals("close")) {
        closeDialog();

        JSONObject obj = new JSONObject();
        obj.put("type", CLOSE_EVENT);

        PluginResult pluginResult = new PluginResult(status, obj);
        pluginResult.setKeepCallback(false);
        return pluginResult;
      } else if (action.equals("openExternal")) {
        result = this.openExternal(args.getString(0), args.optBoolean(1));
        if (result.length() > 0) {
          status = PluginResult.Status.ERROR;
        }
      } else {
        status = PluginResult.Status.INVALID_ACTION;
      }
      return new PluginResult(status, result);
    } catch (JSONException e) {
      return new PluginResult(PluginResult.Status.JSON_EXCEPTION);
    }
  }
  /**
   * Display the specified URL in a custom browser screen.
   *
   * @param args JSONArry of arguments for the action.
   * @return a PluginResult
   */
  private synchronized PluginResult showWebPage(JSONArray args) {
    PluginResult result;

    if (browser == null) {
      try {
        boolean showLocationBar = true;
        String url = args.getString(0);
        JSONObject options = args.getJSONObject(1);

        // Determine whether to show or hide navigation bar.
        if (options != null) {
          showLocationBar = options.optBoolean("showLocationBar", true);
        }

        browser = new CustomBrowser(callbackId);
        if (browser.init(showLocationBar)) {
          uiApp.invokeLater(
              new Runnable() {
                public void run() {
                  uiApp.pushScreen(browser);
                }
              });

          browser.loadURL(url);

          // Must keep the callback for browser URL load and close
          // events.
          result = new PluginResult(PluginResult.Status.OK, "");
          result.setKeepCallback(true);
        } else {
          result =
              new PluginResult(
                  PluginResult.Status.ERROR, TAG + "Failed to initialize CustomBrowser.");
        }
      } catch (JSONException e) {
        return new PluginResult(PluginResult.Status.JSON_EXCEPTION);
      }
    } else {
      result = new PluginResult(PluginResult.Status.ERROR, "ChildBrowser is already open.");
    }

    return result;
  }
  private PluginResult internalRegister(JSONArray data, String callbackId) {
    JSONObject params = null;
    try {
      params = data.getJSONObject(0);
    } catch (JSONException e) {
      e.printStackTrace();
      return new PluginResult(Status.ERROR);
    }

    try {
      mPushManager =
          new PushManager(
              cordova.getActivity(), params.getString("appid"), params.getString("projectid"));
    } catch (JSONException e) {
      e.printStackTrace();
      return new PluginResult(Status.ERROR);
    }

    try {
      if (loggedStart) {
        mPushManager.onStartup(cordova.getActivity(), false);
      } else {
        mPushManager.onStartup(cordova.getActivity(), true);
        loggedStart = true;
      }
    } catch (java.lang.RuntimeException e) {
      e.printStackTrace();
      return new PluginResult(Status.ERROR);
    }

    checkMessage(cordova.getActivity().getIntent());

    callbackIds.put("registerDevice", callbackId);

    PluginResult result = new PluginResult(Status.NO_RESULT);
    result.setKeepCallback(true);
    return result;
  }
 public void triggerTabSelectedEvent(String tabTag) {
   PluginResult res = new PluginResult(PluginResult.Status.OK, tabTag);
   res.setKeepCallback(true);
   this.success(res, callback);
 }
 /**
  * Call the JavaScript error callback for this plugin.
  *
  * @param pluginResult The result to return.
  * @param callbackId The callback id used when calling back into JavaScript.
  */
 public void error(PluginResult pluginResult, String callbackId) {
   this.webView.sendJavascript(pluginResult.toErrorCallbackString(callbackId));
 }
 /**
  * Call the JavaScript success callback for this plugin.
  *
  * <p>This can be used if the execute code for the plugin is asynchronous meaning that execute
  * should return null and the callback from the async operation can call success(...) or
  * error(...)
  *
  * @param pluginResult The result to return.
  * @param callbackId The callback id used when calling back into JavaScript.
  */
 public void success(PluginResult pluginResult, String callbackId) {
   this.webView.sendJavascript(pluginResult.toSuccessCallbackString(callbackId));
 }