page.title=Session Initiation Protocol @jd:body

In this document

  1. Requirements and Limitations
  2. Classes and Interfaces
  3. Creating the Manifest
  4. Creating a SIP Manager
  5. Registering with a SIP Server
  6. Making an Audio Call
  7. Receiving Calls
  8. Testing SIP Applications

Key classes

  1. {@link android.net.sip.SipManager}
  2. {@link android.net.sip.SipProfile}
  3. {@link android.net.sip.SipAudioCall}

Related samples

  1. SipDemo

Android provides an API that supports the Session Initiation Protocol (SIP). This lets you add SIP-based internet telephony features to your applications. Android includes a full SIP protocol stack and integrated call management services that let applications easily set up outgoing and incoming voice calls, without having to manage sessions, transport-level communication, or audio record or playback directly.

Here are examples of the types of applications that might use the SIP API:

Requirements and Limitations

Here are the requirements for developing a SIP application:

SIP API Classes and Interfaces

Here is a summary of the classes and one interface (SipRegistrationListener) that are included in the Android SIP API:

Class/Interface Description
{@link android.net.sip.SipAudioCall} Handles an Internet audio call over SIP.
{@link android.net.sip.SipAudioCall.Listener} Listener for events relating to a SIP call, such as when a call is being received ("on ringing") or a call is outgoing ("on calling").
{@link android.net.sip.SipErrorCode} Defines error codes returned during SIP actions.
{@link android.net.sip.SipManager} Provides APIs for SIP tasks, such as initiating SIP connections, and provides access to related SIP services.
{@link android.net.sip.SipProfile} Defines a SIP profile, including a SIP account, domain and server information.
{@link android.net.sip.SipProfile.Builder} Helper class for creating a SipProfile.
{@link android.net.sip.SipSession} Represents a SIP session that is associated with a SIP dialog or a standalone transaction not within a dialog.
{@link android.net.sip.SipSession.Listener} Listener for events relating to a SIP session, such as when a session is being registered ("on registering") or a call is outgoing ("on calling").
{@link android.net.sip.SipSession.State} Defines SIP session states, such as "registering", "outgoing call", and "in call".
{@link android.net.sip.SipRegistrationListener} An interface that is a listener for SIP registration events.

Creating the Manifest

If you are developing an application that uses the SIP API, remember that the feature is supported only on Android 2.3 (API level 9) and higher versions of the platform. Also, among devices running Android 2.3 (API level 9) or higher, not all devices will offer SIP support.

To use SIP, add the following permissions to your application's manifest:

To ensure that your application can only be installed on devices that are capable of supporting SIP, add the following to your application's manifest:

To control how your application is filtered from devices that do not support SIP (for example, in Android Market), add the following to your application's manifest:

If your application is designed to receive calls, you must also define a receiver ({@link android.content.BroadcastReceiver} subclass) in the application's manifest:

Here are excerpts from the SipDemo manifest:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.example.android.sip">
  ...
     <receiver android:name=".IncomingCallReceiver" android:label="Call Receiver"/>
  ...
  <uses-sdk android:minSdkVersion="9" />
  <uses-permission android:name="android.permission.USE_SIP" />
  <uses-permission android:name="android.permission.INTERNET" />
  ...
  <uses-feature android:name="android.hardware.sip.voip" android:required="true" />
  <uses-feature android:name="android.hardware.wifi" android:required="true" />
  <uses-feature android:name="android.hardware.microphone" android:required="true" />
</manifest>

Creating a SipManager

To use the SIP API, your application must create a {@link android.net.sip.SipManager} object. The {@link android.net.sip.SipManager} takes care of the following in your application:

You instantiate a new {@link android.net.sip.SipManager} as follows:

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

Registering with a SIP Server

A typical Android SIP application involves one or more users, each of whom has a SIP account. In an Android SIP application, each SIP account is represented by a {@link android.net.sip.SipProfile} object.

A {@link android.net.sip.SipProfile} defines a SIP profile, including a SIP account, and domain and server information. The profile associated with the SIP account on the device running the application is called the local profile. The profile that the session is connected to is called the peer profile. When your SIP application logs into the SIP server with the local {@link android.net.sip.SipProfile}, this effectively registers the device as the location to send SIP calls to for your SIP address.

This section shows how to create a {@link android.net.sip.SipProfile}, register it with a SIP server, and track registration events.

You create a {@link android.net.sip.SipProfile} object as follows:

public SipProfile mSipProfile = null;
...

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

The following code excerpt opens the local profile for making calls and/or receiving generic SIP calls. The caller can make subsequent calls through mSipManager.makeAudioCall. This excerpt also sets the action android.SipDemo.INCOMING_CALL, which will be used by an intent filter when the device receives a call (see Setting up an intent filter to receive calls). This is the registration step:

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);

Finally, this code sets a SipRegistrationListener on the {@link android.net.sip.SipManager}. This tracks whether the {@link android.net.sip.SipProfile} was successfully registered with your SIP service provider:

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 onRegistrationFailed(String localProfileUri, int errorCode,
    String errorMessage) {
    updateStatus("Registration failed.  Please check settings.");
}

When your application is done using a profile, it should close it to free associated objects into memory and unregister the device from the server. For example:

public void closeLocalProfile() {
    if (mSipManager == null) {
       return;
    }
    try {
       if (mSipProfile != null) {
          mSipManager.close(mSipProfile.getUriString());
       }
     } catch (Exception ee) {
       Log.d("WalkieTalkieActivity/onDestroy", "Failed to close local profile.", ee);
     }
}

Making an Audio Call

To make an audio call, you must have the following in place:

To make an audio call, you should set up a {@link android.net.sip.SipAudioCall.Listener}. Much of the client's interaction with the SIP stack happens through listeners. In this snippet, you see how the {@link android.net.sip.SipAudioCall.Listener} sets things up after the call is established:

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) {
      // Do something.
   }
};

Once you've set up the {@link android.net.sip.SipAudioCall.Listener}, you can make the call. The {@link android.net.sip.SipManager} method makeAudioCall takes the following parameters:

For example:

 call = mSipManager.makeAudioCall(mSipProfile.getUriString(), sipAddress, listener, 30);

Receiving Calls

To receive calls, a SIP application must include a subclass of {@link android.content.BroadcastReceiver} that has the ability to respond to an intent indicating that there is an incoming call. Thus, you must do the following in your application:

Subclassing BroadcastReceiver

To receive calls, your SIP application must subclass {@link android.content.BroadcastReceiver}. The Android system handles incoming SIP calls and broadcasts an "incoming call" intent (as defined by the application) when it receives a call. Here is the subclassed {@link android.content.BroadcastReceiver} code from SipDemo. To see the full example, go to SipDemo sample, which is included in the SDK samples. For information on downloading and installing the SDK samples, see Getting the Samples.

/*** Listens for incoming SIP calls, intercepts and hands them off to WalkieTalkieActivity.
 */
public class IncomingCallReceiver extends BroadcastReceiver {
    /**
     * Processes the incoming call, answers it, and hands it over to the
     * WalkieTalkieActivity.
     * @param context The context under which the receiver is running.
     * @param intent The intent being received.
     */
    @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();
            }
        }
    }
}

Setting up an intent filter to receive calls

When the SIP service receives a new call, it sends out an intent with the action string provided by the application. In SipDemo, this action string is android.SipDemo.INCOMING_CALL.

This code excerpt from SipDemo shows how the {@link android.net.sip.SipProfile} object gets created with a pending intent based on the action string android.SipDemo.INCOMING_CALL. The PendingIntent object will perform a broadcast when the {@link android.net.sip.SipProfile} receives a call:

public SipManager mSipManager = null;
public SipProfile mSipProfile = null;
...

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);

The broadcast will be intercepted by the intent filter, which will then fire the receiver (IncomingCallReceiver). You can specify an intent filter in your application's manifest file, or do it in code as in the SipDemo sample application's onCreate() method of the application's Activity:

public class WalkieTalkieActivity extends Activity implements View.OnTouchListener {
...
    public IncomingCallReceiver callReceiver;
    ...

    @Override
    public void onCreate(Bundle savedInstanceState) {

       IntentFilter filter = new IntentFilter();
       filter.addAction("android.SipDemo.INCOMING_CALL");
       callReceiver = new IncomingCallReceiver();
       this.registerReceiver(callReceiver, filter);
       ...
    }
    ...
}

Testing SIP Applications

To test SIP applications, you need the following:

To test a SIP application:

  1. On your device, connect to wireless (Settings > Wireless & networks > Wi-Fi > Wi-Fi settings)
  2. Set up your mobile device for testing, as described in Developing on a Device.
  3. Run your application on your mobile device, as described in Developing on a Device.
  4. If you are using Eclipse, you can view the application log output in Eclipse using LogCat (Window > Show View > Other > Android > LogCat).