sip.jd revision 50e990c64fa23ce94efa76b9e72df7f8ec3cee6a
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&#8212;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>&lt;uses-sdk android:minSdkVersion=&quot;9&quot; /&gt;</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">&lt;uses-sdk&gt;</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>&lt;uses-feature android:name=&quot;android.hardware.sip.voip&quot;
156/&gt;</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>&lt;uses-feature&gt;</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">&lt;uses-
163feature&gt;</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>&lt;receiver android:name=&quot;.IncomingCallReceiver&quot; android:label=&quot;Call Receiver&quot;/&gt;</code></li>
170</ul>
171<p>Here are excerpts from the <strong>SipDemo</strong> manifest:</p>
172
173
174
175<pre>&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
176&lt;manifest xmlns:android=&quot;http://schemas.android.com/apk/res/android";
177          package=&quot;com.example.android.sip&quot;&gt;
178  ...
179     &lt;receiver android:name=&quot;.IncomingCallReceiver&quot; android:label=&quot;Call Receiver&quot;/&gt;
180  ...
181  &lt;uses-sdk android:minSdkVersion=&quot;9&quot; /&gt;
182  &lt;uses-permission android:name=&quot;android.permission.USE_SIP&quot; /&gt;
183  &lt;uses-permission android:name=&quot;android.permission.INTERNET&quot; /&gt;
184  ...
185  &lt;uses-feature android:name=&quot;android.hardware.sip.voip&quot; android:required=&quot;true&quot; /&gt;
186  &lt;uses-feature android:name=&quot;android.hardware.wifi&quot; android:required=&quot;true&quot; /&gt;
187  &lt;uses-feature android:name=&quot;android.hardware.microphone&quot; android:required=&quot;true&quot; /&gt;
188&lt;/manifest&gt;
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(&quot;android.SipDemo.INCOMING_CALL&quot;);
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(&quot;Registering with SIP Server...&quot;);
258}
259
260public void onRegistrationDone(String localProfileUri, long expiryTime) {
261    updateStatus(&quot;Ready&quot;);
262}
263   
264public void onRegistrationFailed(String localProfileUri, int errorCode,
265    String errorMessage) {
266    updateStatus(&quot;Registration failed.  Please check settings.&quot;);
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(&quot;WalkieTalkieActivity/onDestroy&quot;, &quot;Failed to close local profile.&quot;, 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&quot;local profile&quot;), and a valid SIP address to receive the call (the
293&quot;peer profile&quot;). 
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   &#64;Override
308   public void onCallEstablished(SipAudioCall call) {
309      call.startAudio();
310      call.setSpeakerMode(true);
311      call.toggleMute();
312         ...
313   }
314   
315   &#64;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>&lt;receiver&gt;</code>. In <strong>SipDemo</strong>, this is
349<code>&lt;receiver android:name=&quot;.IncomingCallReceiver&quot;
350android:label=&quot;Call Receiver&quot;/&gt;</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 &quot;incoming
369call&quot;<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    &#64;Override
388    public void onReceive(Context context, Intent intent) {
389        SipAudioCall incomingCall = null;
390        try {
391            SipAudioCall.Listener listener = new SipAudioCall.Listener() {
392                &#64;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(&quot;android.SipDemo.INCOMING_CALL&quot;); 
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    &#64;Override
454    public void onCreate(Bundle savedInstanceState) {
455
456       IntentFilter filter = new IntentFilter();
457       filter.addAction(&quot;android.SipDemo.INCOMING_CALL&quot;);
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