void encodeAsJsMessage(StringBuilder sb) {
   if (pluginResult == null) {
     sb.append(jsPayloadOrCallbackId);
   } else {
     int status = pluginResult.getStatus();
     boolean success =
         (status == PluginResult.Status.OK.ordinal())
             || (status == PluginResult.Status.NO_RESULT.ordinal());
     sb.append("cordova.callbackFromNative('")
         .append(jsPayloadOrCallbackId)
         .append("',")
         .append(success)
         .append(",")
         .append(status)
         .append(",[");
     switch (pluginResult.getMessageType()) {
       case PluginResult.MESSAGE_TYPE_BINARYSTRING:
         sb.append("atob('").append(pluginResult.getMessage()).append("')");
         break;
       case PluginResult.MESSAGE_TYPE_ARRAYBUFFER:
         sb.append("cordova.require('cordova/base64').toArrayBuffer('")
             .append(pluginResult.getMessage())
             .append("')");
         break;
       default:
         sb.append(pluginResult.getMessage());
     }
     sb.append("],").append(pluginResult.getKeepCallback()).append(");");
   }
 }
    void encodeAsMessage(StringBuilder sb) {
      if (pluginResult == null) {
        sb.append('J').append(jsPayloadOrCallbackId);
        return;
      }
      int status = pluginResult.getStatus();
      boolean noResult = status == PluginResult.Status.NO_RESULT.ordinal();
      boolean resultOk = status == PluginResult.Status.OK.ordinal();
      boolean keepCallback = pluginResult.getKeepCallback();

      sb.append((noResult || resultOk) ? 'S' : 'F')
          .append(keepCallback ? '1' : '0')
          .append(status)
          .append(' ')
          .append(jsPayloadOrCallbackId)
          .append(' ');
      switch (pluginResult.getMessageType()) {
        case PluginResult.MESSAGE_TYPE_BOOLEAN:
          sb.append(pluginResult.getMessage().charAt(0)); // t or f.
          break;
        case PluginResult.MESSAGE_TYPE_NULL: // N
          sb.append('N');
          break;
        case PluginResult.MESSAGE_TYPE_NUMBER: // n
          sb.append('n').append(pluginResult.getMessage());
          break;
        case PluginResult.MESSAGE_TYPE_STRING: // s
          sb.append('s');
          sb.append(pluginResult.getStrMessage());
          break;
        case PluginResult.MESSAGE_TYPE_BINARYSTRING: // S
          sb.append('S');
          sb.append(pluginResult.getMessage());
          break;
        case PluginResult.MESSAGE_TYPE_ARRAYBUFFER: // A
          sb.append('A');
          sb.append(pluginResult.getMessage());
          break;
        case PluginResult.MESSAGE_TYPE_JSON:
        default:
          sb.append(pluginResult.getMessage()); // [ or {
      }
    }
  /** Add a JavaScript statement to the list. */
  public void addPluginResult(PluginResult result, String callbackId) {
    if (callbackId == null) {
      Log.e(LOG_TAG, "Got plugin result with no callbackId", new Throwable());
      return;
    }
    // Don't send anything if there is no result and there is no need to
    // clear the callbacks.
    boolean noResult = result.getStatus() == PluginResult.Status.NO_RESULT.ordinal();
    boolean keepCallback = result.getKeepCallback();
    if (noResult && keepCallback) {
      return;
    }
    JsMessage message = new JsMessage(result, callbackId);
    if (FORCE_ENCODE_USING_EVAL) {
      StringBuilder sb = new StringBuilder(message.calculateEncodedLength() + 50);
      message.encodeAsJsMessage(sb);
      message = new JsMessage(sb.toString());
    }

    enqueueMessage(message);
  }