Java
Android
OriginalQuad incDay 19

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.

android.permission.USE_SIP
android.permission.INTERNET

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.

<use-sdk android:minSdkVersion="9">

Creating a SipManager

public SipManager mSipManager = null;
...
if (mSipManager == null){
    mSipManager = SipManager.newInstance(this);
}

Registering with SIP Server

Create a SipProfile Object

public SipProfile mSipProfile = null;
...
SipProfile.Builder builder = new SipProfile.Builder(username, domain);
builder.setPassword(password);
mSipProfile = builder.build();

Open local profile for making call and receive generic SIP call
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);

Keep track whether the SipProfile was successfully registered
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!");
     }
});

Close Local Profile
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.")
     }
}

Make an Audio Call

To make audio call we have to register for SipAudioCall.Listener handle every call state.

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
 }


};

After register for the listener, we can make an audio call:
call = mSipManager.makeAudioCall(mSipProfile.getUriString(), sipAddress, listener, 30)

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 AndroidManifest.xml, add this following code to declare a receiver:

<receiver android:name=".IncomingCallReceiver" android:label="CallReceiver" />

IncomingCallReceiver class
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();
            }
        }
    }
}

Reference
Session Initiation Protocol | Android Developers