Android SIP Library

This article is talking about developing SIP client in android. Basically, I tried the android native SIP library and I found it a little difficult to understand the basic.

I think that It would be helpful for those who are looking to develop similar kind of application as I do.

# Basic requirement for developing SIP application
1. Android Mobile running on version 2.3 or higher
2. Android Studio (Latest version is recommended)

# Stuffs to be added to Manifest
To use SIP, we have to add the following permissions to the AndroidManifest.xml file.

<pre>android.permission.USE_SIP</pre>
<pre>android.permission.INTERNET</pre>

Add the following line to android manifest file to ensure that the application can only be installed on the devices that are capable of running SIP.
<pre>`<use-sdk android:minSdkVersion="9">`</pre>

# Creating a SipManager
<pre>public SipManager mSipManager = null;
...
if (mSipManager == null){
    mSipManager = SipManager.newInstance(this);
}
</pre>

# Registering with SIP Server
<b>Create a SipProfile Object</b>
<pre>public SipProfile mSipProfile = null;
...
SipProfile.Builder builder = new SipProfile.Builder(username, domain);
builder.setPassword(password);
mSipProfile = builder.build();
</pre>
<b>Open local profile for making call and receive generic SIP call</b>
<pre>Intent intent = new Intent();
intent.setAction("android.SipDemo.INCOMING_CALL");
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, Intent.FILL_IN_DATA);
mSipManager.open(mSipProfile, pendingIntent, null);
</pre>
<b>Keep track whether the SipProfile was successfully registered </b>
<pre>mSipManager.setRegistrationListener(mSipProfile.getUriString(), new SipRegistrationListener() {
     public void onRegistering(String localProfileUri){
         updateStatus("Registering with SIP server.");
     }
     public void onRegistrationDone(String localProfileUri, long expiryTime){
         updateStatus("Ready.");
     }
     public void onRegistering(String localProfileUri, int errorCode, String errorMessage){
         updateStatus("Registration failed!");
     }
});
</pre>
<b>Close Local Profile </b>
<pre>public void closeLocalProfile(){
     if (mSipManager == null){
        return;
     }
     try{
         if (mSipProfile != null){
             mSipManager.close(mSipProfile.getUriString());
         }
     }catch(Exception ee){
         Log.d("TAG", "Failed to close local profile.")
     }
}
</pre>
# Make an Audio Call
To make audio call we have to register for <b>SipAudioCall.Listener</b> handle every call state.
<pre>SipAudioCall.Listener listener = new SipAudioCall.Listener() {
     @Override
     public void onCallEstablished(SipAudioCall call){
          call.startAudio();
          call.setSpeakerMode(true);
          call.toggleMute();
          ...
     }

     @Override
     public void onCallEnded(SipAudioCall call){
          // Call Ended
     }
};
</pre>
After register for the listener, we can make an audio call:
<pre>call = mSipManager.makeAudioCall(mSipProfile.getUriString(), sipAddress, listener, 30)</pre>
# Receiving call
To receive call we need to use android BroadcastReceiver to respond to an intent indicating that there is an incoming call.

First, In <b>AndroidManifest.xml</b>, add this following code to declare a receiver:
<pre>`<receiver android:name=".IncomingCallReceiver" android:label="CallReceiver" />`</pre>
<b>IncomingCallReceiver class</b>
<pre>public class IncomingCallReceiver extends BroadcastReceiver{
     @Override
    public void onReceive(Context context, Intent intent) {
        SipAudioCall incomingCall = null;
        try {
            SipAudioCall.Listener listener = new SipAudioCall.Listener() {
                @Override
                public void onRinging(SipAudioCall call, SipProfile caller) {
                    try {
                        call.answerCall(30);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            };
            WalkieTalkieActivity wtActivity = (WalkieTalkieActivity) context;
            incomingCall = wtActivity.mSipManager.takeAudioCall(intent, listener);
            incomingCall.answerCall(30);
            incomingCall.startAudio();
            incomingCall.setSpeakerMode(true);
            if(incomingCall.isMuted()) {
                incomingCall.toggleMute();
            }
            wtActivity.call = incomingCall;
            wtActivity.updateStatus(incomingCall);
        } catch (Exception e) {
            if (incomingCall != null) {
                incomingCall.close();
            }
        }
    }
}
</pre>

Reference
[Session Initiation Protocol | Android Developers](https://developer.android.com/guide/topics/connectivity/sip.html)