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