I'm trying to implement an RTC in my Android app.
My Android client is meant to be the offer.

I use setLocalDescription and send my SessionDescription.
The problem is when I create my own SessionDescription and try to use setRemoteDescription - I get a response that my SessionDescription is null although is isn't.
See the following code.

```
public class OfferActivity extends AppCompatActivity implements View.OnClickListener {

    final private String TAG = "App";

    private PeerConnectionFactory mFactory;
    private PeerConnection mPeerConnection;
    private DataChannel mDataChannel;
    private MediaConstraints mConstraints;

    PeerConnection.Observer mPeerConnectionObserver = new PeerConnection.Observer() {
        @Override
        public void onIceCandidate(IceCandidate iceCandidate) {
            IceCandidate candidate = new IceCandidate(iceCandidate.sdpMid, iceCandidate.sdpMLineIndex, "candidate");  // TODO: Edit
            Log.d(TAG, "pcObserver1 onIceCandidate() param: " + candidate.toString());
            mPeerConnection.addIceCandidate(candidate);
        }

        @Override
        public void onSignalingChange(PeerConnection.SignalingState signalingState) {
        }

        @Override
        public void onIceConnectionChange(PeerConnection.IceConnectionState iceConnectionState) {
        }

        @Override
        public void onIceGatheringChange(PeerConnection.IceGatheringState iceGatheringState) {
        }

        @Override
        public void onAddStream(MediaStream mediaStream) {
        }

        @Override
        public void onRemoveStream(MediaStream mediaStream) {
        }

        @Override
        public void onDataChannel(DataChannel dataChannel) {
            mDataChannel = dataChannel;
            mDataChannel.registerObserver(mDataChannelObserver);
        }

        @Override
        public void onRenegotiationNeeded() {
        }
    };

    DataChannel.Observer mDataChannelObserver = new DataChannel.Observer() {
        @Override
        public void onStateChange() {
            Log.d(TAG, "mDataChannelObserver onStateChange() " + mDataChannel.state().name());

            if (mDataChannel.state() == DataChannel.State.OPEN) {
                String data = mEt.getText().toString();
                ByteBuffer buffer = ByteBuffer.wrap(data.getBytes());
                mDataChannel.send(new DataChannel.Buffer(buffer, false));
            }
        }

        @Override
        public void onMessage(DataChannel.Buffer buffer) {
            Log.d(TAG, "mDataChannelObserver onMessage()");
            if (buffer.binary == false) {
                int limit = buffer.data.limit();
                byte[] datas = new byte[limit];
                buffer.data.get(datas);
                final String tmp = new String(datas);
                Log.d(TAG, "mDataChannelObserver onMessage: " + tmp);
                addText("mDataChannelObserver", tmp);
            }
        }
    };

    SdpObserver mSdpLocalObserver = new SdpObserver() {
        @Override
        public void onCreateSuccess(SessionDescription desc) {

            final SessionDescription.Type typeEnum = desc.type;
            final String type = typeEnum.canonicalForm();
            final String sdp = desc.description;

            if (typeEnum == SessionDescription.Type.OFFER) {
                mPeerConnection.setLocalDescription(mSdpLocalObserver, desc);
                // TODO: Here we will have the code that gets the other peer sdp
            } else if (typeEnum == SessionDescription.Type.ANSWER) {
                mPeerConnection.setRemoteDescription(mSdpLocalObserver, desc);
            } else {

                Log.d(TAG, "Something else was found at onCreateSuccess");
            }
            // TODO: This is debug only. the "setLocalDescription" does not need javascript interfaces (JSON)
            try {
                final JSONObject json = new JSONObject();
                json.put("type", type);
                json.put("sdp", sdp);
                Log.d(TAG, "mSdpLocalObserver onCreateSuccess() > sdp: " + json.toString());
            } catch (org.json.JSONException ex) {
            }
        }

        @Override
        public void onSetSuccess() {
            Log.d(TAG, "mSdpLocalObserver onCreateSuccess()");
        }

        @Override
        public void onCreateFailure(String s) {
            Log.d(TAG, "mSdpLocalObserver onCreateFailure() " + s);
        }

        @Override
        public void onSetFailure(String s) {
            Log.d(TAG, "mSdpLocalObserver onSetFailure() " + s);
        }
    };

    private TextView mTv;
    private EditText mEt;
    private Button mBtn;
    private EditText mEtRegister;
    private Button mBtnRegister;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mTv = (TextView) findViewById(R.id.mTv);
        mEt = (EditText) findViewById(R.id.mEt);
        mBtn = (Button) findViewById(R.id.mBtn);
        mEtRegister = (EditText) findViewById(R.id.mEtRegister);
        mBtnRegister = (Button) findViewById(R.id.mBtnRegister);
        mBtn.setOnClickListener(this);
        mBtnRegister.setOnClickListener(this);

        PeerConnectionFactory.initializeAndroidGlobals(getApplicationContext(), true, true, true, null);
        mFactory = new PeerConnectionFactory();

        final List<PeerConnection.IceServer> iceServers = new LinkedList<>();
        iceServers.add(new PeerConnection.IceServer("stun:xx.xx.xxx.xxx")); // TODO: Edit

        mConstraints = new MediaConstraints();
        mConstraints.optional.add(new MediaConstraints.KeyValuePair("DtlsSrtpKeyAgreement", "true"));
        mConstraints.optional.add(new MediaConstraints.KeyValuePair("RtpDataChannels", "true"));

        mPeerConnecti

                on = mFactory.createPeerConnection(iceServers, mConstraints, mPeerConnectionObserver);

        mDataChannel = mPeerConnection.createDataChannel("test", new DataChannel.Init()); // TODO: Edit

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "onDestroy()");
        if (mDataChannel != null) {
            mDataChannel.close();
            mDataChannel.unregisterObserver();
        }
        if (mPeerConnection != null) {
            mPeerConnection.close();

        }
    }

    @Override
    public void onClick(View v) {
        if (v == mBtnRegister) {
            String text = mEtRegister.getText().toString(); // .replace("\\r\\n","");
            final SessionDescription description = new SessionDescription(SessionDescription.Type.ANSWER, text);
            mPeerConnection.setRemoteDescription(mSdpLocalObserver, null);
        }
    }

    private DataChannel.Buffer send(String data) {
        ByteBuffer buffer = ByteBuffer.wrap(data.getBytes());
        return new DataChannel.Buffer(buffer, false);
    }

    private void addText(final String who, final String what) {
        OfferActivity.this.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                final String text = mTv.getText().toString() + "\n";
                mTv.setText(text + who + ": " + what);
                mEt.setText("");
            }
        });
    }

}

```

My Logs:

```
01-19 16:12:51.447 9171-9239/com.walkme.rtc D/sample: pcObserver1 onRenegotiationNeeded()
01-19 16:12:51.879 9171-9239/com.walkme.rtc D/sample: pcObserver1 onSignalingChange() HAVE_LOCAL_OFFER
01-19 16:12:51.881 9171-9239/com.walkme.rtc D/sample: mSdpLocalObserver onCreateSuccess() > sdp: {"type":"offer","sdp":"v=0\r\no=- 8050881100630094562 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\na=group:BUNDLE data\r\na=msid-semantic: WMS\r\nm=application 9 RTP\/SAVPF 101\r\nc=IN IP4 0.0.0.0\r\nb=AS:30\r\na=rtcp:9 IN IP4 0.0.0.0\r\na=ice-ufrag:+f0buF4V2OXNT4sI\r\na=ice-pwd:\/QDilxDBndczNuvgPIBXZ7je\r\na=fingerprint:sha-256 E4:FB:1E:80:16:B8:4E:F9:B1:E3:81:B6:09:83:95:F3:B3:C2:34:DC:88:F4:C8:DF:9B:50:8A:00:0E:4D:AC:75\r\na=setup:actpass\r\na=mid:data\r\na=sendrecv\r\na=rtcp-mux\r\na=rtpmap:101 google-data\/90000\r\na=ssrc:1715303496 cname:NVNcmn2VpGpsfyFJ\r\na=ssrc:1715303496 msid:test test\r\na=ssrc:1715303496 mslabel:test\r\na=ssrc:1715303496 label:test\r\n"}
01-19 16:12:51.882 9171-9239/com.walkme.rtc D/sample: pcObserver1 onIceGatheringChange() GATHERING
01-19 16:12:51.883 9171-9239/com.walkme.rtc D/sample: pcObserver1 onIceGatheringChange() GATHERING
01-19 16:12:51.883 9171-9239/com.walkme.rtc D/sample: sdpObserver1 onCreateSuccess()
01-19 16:12:51.884 9171-9239/com.walkme.rtc D/sample: pcObserver1 onIceCandidate() param: data:0:candidate
01-19 16:12:51.885 9171-9239/com.walkme.rtc D/sample: pcObserver1 onIceCandidate() param: data:0:candidate
01-19 16:12:51.985 9171-9239/com.walkme.rtc D/sample: pcObserver1 onIceCandidate() param: data:0:candidate
01-19 16:12:51.986 9171-9239/com.walkme.rtc D/sample: pcObserver1 onIceCandidate() param: data:0:candidate
01-19 16:12:52.038 9171-9239/com.walkme.rtc D/sample: pcObserver1 onIceCandidate() param: data:0:candidate
01-19 16:12:52.039 9171-9239/com.walkme.rtc D/sample: pcObserver1 onIceCandidate() param: data:0:candidate
01-19 16:12:52.039 9171-9239/com.walkme.rtc D/sample: pcObserver1 onIceGatheringChange() COMPLETE
01-19 16:13:32.985 9171-9239/com.walkme.rtc D/sample: sdpObserver1 onSetFailure() SessionDescription is NULL.
01-19 16:14:16.864 11776-11844/com.walkme.rtc D/sample: pcObserver1 onRenegotiationNeeded()
01-19 16:14:16.974 11776-11844/com.walkme.rtc D/sample: pcObserver1 onSignalingChange() HAVE_LOCAL_OFFER
01-19 16:14:16.977 11776-11844/com.walkme.rtc D/sample: mSdpLocalObserver onCreateSuccess() > sdp: {"type":"offer","sdp":"v=0\r\no=- 3146545619962464613 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\na=group:BUNDLE data\r\na=msid-semantic: WMS\r\nm=application 9 RTP\/SAVPF 101\r\nc=IN IP4 0.0.0.0\r\nb=AS:30\r\na=rtcp:9 IN IP4 0.0.0.0\r\na=ice-ufrag:W3sKNep8dXP\/Ind5\r\na=ice-pwd:oOy9NblGeZxRWL\/bxSnFU8KD\r\na=fingerprint:sha-256 78:2E:EF:58:AD:11:E3:29:34:7C:94:48:E7:DC:98:90:17:D6:5E:0B:DC:72:3E:4A:5A:35:7F:C5:F8:D4:06:81\r\na=setup:actpass\r\na=mid:data\r\na=sendrecv\r\na=rtcp-mux\r\na=rtpmap:101 google-data\/90000\r\na=ssrc:3989867427 cname:JKXfZ0vrlT1jdURT\r\na=ssrc:3989867427 msid:test test\r\na=ssrc:3989867427 mslabel:test\r\na=ssrc:3989867427 label:test\r\n"}
01-19 16:14:16.978 11776-11844/com.walkme.rtc D/sample: pcObserver1 onIceGatheringChange() GATHERING
01-19 16:14:16.978 11776-11844/com.walkme.rtc D/sample: pcObserver1 onIceGatheringChange() GATHERING
01-19 16:14:16.978 11776-11844/com.walkme.rtc D/sample: sdpObserver1 onCreateSuccess()
01-19 16:14:16.980 11776-11844/com.walkme.rtc D/sample: pcObserver1 onIceCandidate() param: data:0:candidate
01-19 16:14:16.981 11776-11844/com.walkme.rtc D/sample: pcObserver1 onIceCandidate() param: data:0:candidate
01-19 16:14:17.082 11776-11844/com.walkme.rtc D/sample: pcObserver1 onIceCandidate() param: data:0:candidate
01-19 16:14:17.082 11776-11844/com.walkme.rtc D/sample: pcObserver1 onIceCandidate() param: data:0:candidate
01-19 16:14:17.136 11776-11844/com.walkme.rtc D/sample: pcObserver1 onIceCandidate() param: data:0:candidate
01-19 16:14:17.137 11776-11844/com.walkme.rtc D/sample: pcObserver1 onIceCandidate() param: data:0:candidate
01-19 16:14:17.138 11776-11844/com.walkme.rtc D/sample: pcObserver1 onIceGatheringChange() COMPLETE
01-19 16:14:22.769 11776-11844/com.walkme.rtc D/sample: sdpObserver1 onSetFailure() SessionDescription is NULL.
01-19 16:31:51.241 29355-29414/com.walkme.rtc D/sample: pcObserver1 onRenegotiationNeeded()

```

**EDIT**

After further inspection the problem was with the codecs.
What I did was simply get the data as a string of json and then used JsonObject.