1page.title=Session Initiation Protocol 2@jd:body 3<div id="qv-wrapper"> 4<div id="qv"> 5 <h2>In this document</h2> 6 <ol> 7 8 <li><a href="#requirements">Requirements and Limitations</a></li> 9 <li><a href="#classes">Classes and Interfaces</a></li> 10 <li><a href="#manifest">Creating the Manifest</a></li> 11 <li><a href="#manager">Creating a SIP Manager</a></li> 12 <li><a href="#profiles">Registering with a SIP Server</a></li> 13 <li><a href="#audio">Making an Audio Call</a></li> 14 <li><a href="#receiving">Receiving Calls</a></li> 15 <li><a href="#testing">Testing SIP Applications</a></li> 16 </ol> 17 18 <h2>Key classes</h2> 19 <ol> 20 <li>{@link android.net.sip.SipManager}</li> 21 <li>{@link android.net.sip.SipProfile}</li> 22 <li>{@link android.net.sip.SipAudioCall}</li> 23 24 </ol> 25 26 <h2>Related samples</h2> 27 <ol> 28 <li> <a href="{@docRoot}resources/samples/SipDemo/index.html"> SipDemo</a></li> 29 </ol> 30 </div> 31</div> 32 33<p>Android provides an API that supports the Session Initiation Protocol (SIP). 34This lets you add SIP-based internet telephony features to your applications. 35Android includes a full SIP protocol stack and integrated call management 36services that let applications easily set up outgoing and incoming voice calls, 37without having to manage sessions, transport-level communication, or audio 38record or playback directly.</p> 39 40<p>Here are examples of the types of applications that might use the SIP API:</p> 41<ul> 42 <li>Video conferencing.</li> 43 <li>Instant messaging.</li> 44</ul> 45<h2 id="requirements">Requirements and Limitations</h2> 46<p>Here are the requirements for developing a SIP application:</p> 47<ul> 48 49 <li>You must have a mobile device that is running Android 2.3 or higher. </li> 50 51 <li>SIP runs over a wireless data connection, so your device must have a data 52connection (with a mobile data service or Wi-Fi)</span>. This means that you 53can't test on AVD—you can only test on a physical device. For details, see 54<a href="#testing">Testing SIP Applications</a>.</li> 55 56 <li>Each participant in the application's communication session must have a 57SIP account. There are many different SIP providers that offer SIP accounts.</li> 58</ul> 59 60 61<h2 id="classes">SIP API Classes and Interfaces</h2> 62 63<p>Here is a summary of the classes and one interface 64(<code>SipRegistrationListener</code>) that are included in the Android SIP 65API:</p> 66 67<table> 68 <thead> 69 <tr> 70 <th>Class/Interface</th> 71 <th>Description</th> 72 </tr> 73 </thead> 74 <tbody> 75 <tr> 76 <td>{@link android.net.sip.SipAudioCall}</td> 77 <td>Handles an Internet audio call over SIP.</td> 78 </tr> 79 <tr> 80 <td>{@link android.net.sip.SipAudioCall.Listener}</td> 81 <td>Listener for events relating to a SIP call, such as when a call is being 82received ("on ringing") or a call is outgoing ("on calling").</td> 83 </tr> 84 <tr> 85 <td>{@link android.net.sip.SipErrorCode}</td> 86 <td>Defines error codes returned during SIP actions.</td> 87 </tr> 88 <tr> 89 <td>{@link android.net.sip.SipManager}</td> 90 <td>Provides APIs for SIP tasks, such as initiating SIP connections, and provides access 91to related SIP services.</td> 92 </tr> 93 <tr> 94 <td>{@link android.net.sip.SipProfile}</td> 95 <td>Defines a SIP profile, including a SIP account, domain and server information. 96</td> 97 </tr> 98 <tr> 99 <td>{@link android.net.sip.SipProfile.Builder}</td> 100 <td>Helper class for creating a SipProfile.</td> 101 </tr> 102 <tr> 103 <td>{@link android.net.sip.SipSession}</td> 104 <td>Represents a SIP session that is associated with a SIP dialog or a standalone transaction 105not within a dialog.</td> 106 </tr> 107 <tr> 108 <td>{@link android.net.sip.SipSession.Listener}</td> 109 <td>Listener for events relating to a SIP session, such as when a session is being registered 110("on registering") or a call is outgoing ("on calling"). </td> 111 </tr> 112 <tr> 113 <td>{@link android.net.sip.SipSession.State}</td> 114 <td>Defines SIP session states, such as "registering", "outgoing call", and "in call". </td> 115 </tr> 116 <tr> 117 <td>{@link android.net.sip.SipRegistrationListener}</td> 118 <td>An interface that is a listener for SIP registration events.</td> 119 </tr> 120 </tbody> 121</table> 122 123<h2 id="manifest">Creating the Manifest</h2> 124 125<p>If you are developing an application that uses the SIP API, remember that the 126feature is supported only on Android 2.3 (API level 9) and higher versions of 127the platform. Also, among devices running Android 2.3 (API level 9) or higher, 128not all devices will offer SIP support.</p> 129 130<p>To use SIP, add the following permissions to your application's manifest:</p> 131<ul> 132 <li><code>android.permission.USE_SIP</code></li> 133 <li><code>android.permission.INTERNET</code></li> 134</ul> 135 136<p> To ensure that your application can only be installed on devices that are 137capable of supporting SIP, add the following to your application's 138manifest:</p> 139 140<ul> 141 <li><code><uses-sdk android:minSdkVersion="9" /></code>. This 142 indicates that your application requires Android 2.3 or higher. For more 143information, see <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#ApiLevels">API 144Levels</a> and the documentation for the <a 145href="{@docRoot}guide/topics/manifest/uses-sdk-element.html"><uses-sdk></a 146> element.</li> 147</ul> 148 149<p>To control how your application is filtered from devices that do not support 150SIP (for example, on Google Play), add the following to your application's 151manifest:</p> 152 153<ul> 154 155 <li><code><uses-feature android:name="android.hardware.sip.voip" 156/></code>. This states that your application uses the SIP API. The 157declaration should include an <code>android:required</code> attribute that 158indicates whether you want the application to be filtered from devices that do 159not offer SIP support. Other <code><uses-feature></code> declarations 160may also be needed, depending on your implementation. For more information, 161see the documentation for the <a 162href="{@docRoot}guide/topics/manifest/uses-feature-element.html"><uses- 163feature></a> element.</li> 164 165</ul> 166<p>If your application is designed to receive calls, you must also define a receiver ({@link android.content.BroadcastReceiver} subclass) in the application's manifest: </p> 167 168<ul> 169 <li><code><receiver android:name=".IncomingCallReceiver" android:label="Call Receiver"/></code></li> 170</ul> 171<p>Here are excerpts from the <strong>SipDemo</strong> manifest:</p> 172 173 174 175<pre><?xml version="1.0" encoding="utf-8"?> 176<manifest xmlns:android="http://schemas.android.com/apk/res/android" 177 package="com.example.android.sip"> 178 ... 179 <receiver android:name=".IncomingCallReceiver" android:label="Call Receiver"/> 180 ... 181 <uses-sdk android:minSdkVersion="9" /> 182 <uses-permission android:name="android.permission.USE_SIP" /> 183 <uses-permission android:name="android.permission.INTERNET" /> 184 ... 185 <uses-feature android:name="android.hardware.sip.voip" android:required="true" /> 186 <uses-feature android:name="android.hardware.wifi" android:required="true" /> 187 <uses-feature android:name="android.hardware.microphone" android:required="true" /> 188</manifest> 189</pre> 190 191 192<h2 id="manager">Creating a SipManager</h2> 193 194<p>To use the SIP API, your application must create a {@link 195android.net.sip.SipManager} object. The {@link android.net.sip.SipManager} takes 196care of the following in your application:</p> 197 198<ul> 199 <li>Initiating SIP sessions.</li> 200 <li>Initiating and receiving calls.</li> 201 <li>Registering and unregistering with a SIP provider.</li> 202 <li>Verifying session connectivity.</li> 203</ul> 204<p>You instantiate a new {@link android.net.sip.SipManager} as follows:</p> 205<pre>public SipManager mSipManager = null; 206... 207if(mSipManager == null) { 208 mSipManager = SipManager.newInstance(this); 209}</pre> 210<h2 id="profiles">Registering with a SIP Server</h2> 211 212<p>A typical Android SIP application involves one or more users, each of whom 213has a SIP account. In an Android SIP application, each SIP account is 214represented by a {@link android.net.sip.SipProfile} object.</p> 215 216<p>A {@link android.net.sip.SipProfile} defines a SIP profile, including a SIP 217account, and domain and server information. The profile associated with the SIP 218account on the device running the application is called the <em>local 219profile</em>. The profile that the session is connected to is called the 220<em>peer profile</em>. When your SIP application logs into the SIP server with 221the local {@link android.net.sip.SipProfile}, this effectively registers the 222device as the location to send SIP calls to for your SIP address.</p> 223 224<p>This section shows how to create a {@link android.net.sip.SipProfile}, 225register it with a SIP server, and track registration events.</p> 226 227<p>You create a {@link android.net.sip.SipProfile} object as follows:</p> 228<pre> 229public SipProfile mSipProfile = null; 230... 231 232SipProfile.Builder builder = new SipProfile.Builder(username, domain); 233builder.setPassword(password); 234mSipProfile = builder.build();</pre> 235 236<p>The following code excerpt opens the local profile for making calls and/or 237receiving generic SIP calls. The caller can make subsequent calls through 238<code>mSipManager.makeAudioCall</code>. This excerpt also sets the action 239<code>android.SipDemo.INCOMING_CALL</code>, which will be used by an intent 240filter when the device receives a call (see <a href="#intent_filter">Setting up 241an intent filter to receive calls</a>). This is the registration step:</p> 242 243<pre>Intent intent = new Intent(); 244intent.setAction("android.SipDemo.INCOMING_CALL"); 245PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, Intent.FILL_IN_DATA); 246mSipManager.open(mSipProfile, pendingIntent, null);</pre> 247 248<p>Finally, this code sets a <code>SipRegistrationListener</code> on the {@link 249android.net.sip.SipManager}. This tracks whether the {@link 250android.net.sip.SipProfile} was successfully registered with your SIP service 251provider:<br> 252</p> 253 254<pre>mSipManager.setRegistrationListener(mSipProfile.getUriString(), new SipRegistrationListener() { 255 256public void onRegistering(String localProfileUri) { 257 updateStatus("Registering with SIP Server..."); 258} 259 260public void onRegistrationDone(String localProfileUri, long expiryTime) { 261 updateStatus("Ready"); 262} 263 264public void onRegistrationFailed(String localProfileUri, int errorCode, 265 String errorMessage) { 266 updateStatus("Registration failed. Please check settings."); 267}</pre> 268 269 270<p>When your application is done using a profile, it should close it to free 271associated objects into memory and unregister the device from the server. For 272example:</p> 273 274<pre>public void closeLocalProfile() { 275 if (mSipManager == null) { 276 return; 277 } 278 try { 279 if (mSipProfile != null) { 280 mSipManager.close(mSipProfile.getUriString()); 281 } 282 } catch (Exception ee) { 283 Log.d("WalkieTalkieActivity/onDestroy", "Failed to close local profile.", ee); 284 } 285}</pre> 286 287<h2 id="audio">Making an Audio Call</h2> 288<p>To make an audio call, you must have the following in place:</p> 289<ul> 290 291 <li>A {@link android.net.sip.SipProfile} that is making the call (the 292"local profile"), and a valid SIP address to receive the call (the 293"peer profile"). 294 295 <li>A {@link android.net.sip.SipManager} object. </li> 296</ul> 297 298<p>To make an audio call, you should set up a {@link 299android.net.sip.SipAudioCall.Listener}. Much of the client's interaction with 300the SIP stack happens through listeners. In this snippet, you see how the {@link 301android.net.sip.SipAudioCall.Listener} sets things up after the call is 302established:</p> 303 304<pre> 305SipAudioCall.Listener listener = new SipAudioCall.Listener() { 306 307 @Override 308 public void onCallEstablished(SipAudioCall call) { 309 call.startAudio(); 310 call.setSpeakerMode(true); 311 call.toggleMute(); 312 ... 313 } 314 315 @Override 316 public void onCallEnded(SipAudioCall call) { 317 // Do something. 318 } 319};</pre> 320 321<p>Once you've set up the {@link android.net.sip.SipAudioCall.Listener}, you can 322make the call. The {@link android.net.sip.SipManager} method 323<code>makeAudioCall</code> takes the following parameters:</p> 324 325<ul> 326 <li>A local SIP profile (the caller).</li> 327 <li>A peer SIP profile (the user being called).</li> 328 329 <li>A {@link android.net.sip.SipAudioCall.Listener} to listen to the call 330events from {@link android.net.sip.SipAudioCall}. This can be <code>null</code>, 331but as shown above, the listener is used to set things up once the call is 332established.</li> 333 334 <li>The timeout value, in seconds.</li> 335</ul> 336<p>For example:</p> 337<pre> call = mSipManager.makeAudioCall(mSipProfile.getUriString(), sipAddress, listener, 30);</pre> 338 339<h2 id="receiving">Receiving Calls</h2> 340 341<p>To receive calls, a SIP application must include a subclass of {@link 342android.content.BroadcastReceiver} that has the ability to respond to an intent 343indicating that there is an incoming call. Thus, you must do the following in 344your application:</p> 345 346<ul> 347 <li>In <code>AndroidManifest.xml</code>, declare a 348<code><receiver></code>. In <strong>SipDemo</strong>, this is 349<code><receiver android:name=".IncomingCallReceiver" 350android:label="Call Receiver"/></code>.</li> 351 352 <li>Implement the receiver, which is a subclass of {@link 353android.content.BroadcastReceiver}. In <strong>SipDemo</strong>, this is 354<code>IncomingCallReceiver</code>.</li> 355 356 <li>Initialize the local profile ({@link android.net.sip.SipProfile}) with a 357pending intent that fires your receiver when someone calls the local profile. 358</li> 359 360 <li>Set up an intent filter that filters by the action that represents an 361incoming call. In <strong>SipDemo</strong>, this action is 362<code>android.SipDemo.INCOMING_CALL</code>. </li> 363</ul> 364<h4 id="BroadcastReceiver">Subclassing BroadcastReceiver</h4> 365 366<p>To receive calls, your SIP application must subclass {@link 367android.content.BroadcastReceiver}. <span id="internal-source-marker_0.">The 368Android system handles incoming SIP calls and broadcasts an "incoming 369call"<code></code> intent (as defined by the application) when it receives 370a call.</span> Here is the subclassed {@link android.content.BroadcastReceiver} 371code from <strong>SipDemo</strong>. To see the full example, go to <a 372href="{@docRoot}resources/samples/SipDemo/index.html">SipDemo sample</a>, which 373is included in the SDK samples. For information on downloading and installing 374the SDK samples, see <a 375href="{@docRoot}resources/samples/get.html"> 376Getting the Samples</a>. </p> 377 378<pre>/*** Listens for incoming SIP calls, intercepts and hands them off to WalkieTalkieActivity. 379 */ 380public class IncomingCallReceiver extends BroadcastReceiver { 381 /** 382 * Processes the incoming call, answers it, and hands it over to the 383 * WalkieTalkieActivity. 384 * @param context The context under which the receiver is running. 385 * @param intent The intent being received. 386 */ 387 @Override 388 public void onReceive(Context context, Intent intent) { 389 SipAudioCall incomingCall = null; 390 try { 391 SipAudioCall.Listener listener = new SipAudioCall.Listener() { 392 @Override 393 public void onRinging(SipAudioCall call, SipProfile caller) { 394 try { 395 call.answerCall(30); 396 } catch (Exception e) { 397 e.printStackTrace(); 398 } 399 } 400 }; 401 WalkieTalkieActivity wtActivity = (WalkieTalkieActivity) context; 402 incomingCall = wtActivity.mSipManager.takeAudioCall(intent, listener); 403 incomingCall.answerCall(30); 404 incomingCall.startAudio(); 405 incomingCall.setSpeakerMode(true); 406 if(incomingCall.isMuted()) { 407 incomingCall.toggleMute(); 408 } 409 wtActivity.call = incomingCall; 410 wtActivity.updateStatus(incomingCall); 411 } catch (Exception e) { 412 if (incomingCall != null) { 413 incomingCall.close(); 414 } 415 } 416 } 417} 418</pre> 419 420<h4 id="intent_filter">Setting up an intent filter to receive calls</h4> 421 422<p>When the SIP service receives a new call, it sends out an intent with the 423action string provided by the application. In SipDemo, this action string is 424<code>android.SipDemo.INCOMING_CALL</code>. </p> 425<p>This code excerpt from <strong>SipDemo</strong> shows how the {@link 426android.net.sip.SipProfile} object gets created with a pending intent based on 427the action string <code>android.SipDemo.INCOMING_CALL</code>. The 428<code>PendingIntent</code> object will perform a broadcast when the {@link 429android.net.sip.SipProfile} receives a call:</p> 430 431<pre> 432public SipManager mSipManager = null; 433public SipProfile mSipProfile = null; 434... 435 436Intent intent = new Intent(); 437intent.setAction("android.SipDemo.INCOMING_CALL"); 438PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, Intent.FILL_IN_DATA); 439mSipManager.open(mSipProfile, pendingIntent, null);</pre> 440 441<p>The broadcast will be intercepted by the intent filter, which will then fire 442the receiver (<code>IncomingCallReceiver</code>). You can specify an intent 443filter in your application's manifest file, or do it in code as in the <strong>SipDemo</strong> 444sample application's <code>onCreate()</code> method 445of the application's <code>Activity</code>:</p> 446 447<pre> 448public class WalkieTalkieActivity extends Activity implements View.OnTouchListener { 449... 450 public IncomingCallReceiver callReceiver; 451 ... 452 453 @Override 454 public void onCreate(Bundle savedInstanceState) { 455 456 IntentFilter filter = new IntentFilter(); 457 filter.addAction("android.SipDemo.INCOMING_CALL"); 458 callReceiver = new IncomingCallReceiver(); 459 this.registerReceiver(callReceiver, filter); 460 ... 461 } 462 ... 463} 464</pre> 465 466 467<h2 id="testing">Testing SIP Applications</h2> 468 469<p>To test SIP applications, you need the following:</p> 470<ul> 471<li>A mobile device that is running Android 2.3 or higher. SIP runs over 472wireless, so you must test on an actual device. Testing on AVD won't work.</li> 473<li>A SIP account. There are many different SIP providers that offer SIP accounts.</li> 474<li>If you are placing a call, it must also be to a valid SIP account. </li> 475</ul> 476<p>To test a SIP application:</p> 477<ol> 478 479<li>On your device, connect to wireless (<strong>Settings > Wireless & networks 480> Wi-Fi > Wi-Fi settings</strong>)</li> 481<li>Set up your mobile device for testing, as described in <a 482href="{@docRoot}tools/device.html">Developing on a Device</a>.</li> 483<li>Run your application on your mobile device, as described in <a 484href="{@docRoot}tools/device.html">Developing on a Device</a>.</li> 485 486<li>If you are using Eclipse, you can view the application log output in Eclipse 487using LogCat (<strong>Window > Show View > Other > Android > 488LogCat</strong>).</li> 489</ol> 490 491