boolean listenOn(String myId) { // Todo: return success?
   if (localMediaStream == null) { // Not true for streaming?
     mRtcListener.onDebug(new PnRTCMessage("Need to add media stream before you can connect."));
     return false;
   }
   if (this.id != null) { // Prevent listening on multiple channels.
     mRtcListener.onDebug(
         new PnRTCMessage(
             "Already listening on " + this.id + ". Cannot have multiple connections."));
     return false;
   }
   this.id = myId;
   subscribe(myId);
   return true;
 }
  /**
   * Send SDP Offers/Answers nd ICE candidates to peers.
   *
   * @param toID The id or "number" that you wish to transmit a message to.
   * @param packet The JSON data to be transmitted
   */
  void transmitMessage(String toID, JSONObject packet) {
    if (this.id == null) { // Not logged in. Put an error in the debug cb.
      mRtcListener.onDebug(new PnRTCMessage("Cannot transmit before calling Client.connect"));
    }
    try {
      JSONObject message = new JSONObject();
      message.put(PnRTCMessage.JSON_PACKET, packet);
      message.put(PnRTCMessage.JSON_ID, ""); // Todo: session id, unused in js SDK?
      message.put(PnRTCMessage.JSON_NUMBER, this.id);
      this.mPubNub.publish(
          toID,
          message,
          new Callback() { // Todo: reconsider callback.
            @Override
            public void successCallback(String channel, Object message, String timetoken) {
              mRtcListener.onDebug(new PnRTCMessage((JSONObject) message));
            }

            @Override
            public void errorCallback(String channel, PubnubError error) {
              mRtcListener.onDebug(new PnRTCMessage(error.errorObject));
            }
          });
    } catch (JSONException e) {
      e.printStackTrace();
    }
  }