Contextual Voice/Communications as an App or App Feature (on Android)


Published on

Contextual Voice/Communications as an App or App Feature
(Enabling Voice Apps on Android)

C. Enrique Ortiz
July 12, 2013
Google Dev Fest 2013

Published in: Mobile
1 Like
  • Be the first to comment

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

Contextual Voice/Communications as an App or App Feature (on Android)

  1. 1. Contextual Voice/Communication as an App or App-Feature C. Enrique Ortiz July 12, 2013 Google Dev Fest 2013 Revised Feb 2015 (Enabling Voice on Android Apps)
  2. 2. Evolution of Voice on Mobile (1) •  Mobile has truly gone through a period of tremendous evolution and growth – Voice has always been a fundamental feature of the mobile phone, and it will always be •  Yet in the world or era of “data”, voice has been treated as “legacy stuff”, separate and driven by its own experience, drivers, and infrastructure; voice just works, but separate, under Operator control
  3. 3. Evolution of Voice on Mobile (2) •  Voice is slowly becoming a “data app” — Voice as an app or an app-feature •  Multi-model user experience •  These are based on SIP and WebRTC stacks & clients that you can download and use, point-to- point or via the old PSTN •  The move to all IP wireless networks (LTE) translates to ease of adapting Voice on your app.
  4. 4. Voice and Apps -- Use Cases •  The Telephone Number as Personas –  One device, multiple Personas –  Private/Personal vs. Public or Work/Business –  Voice or communication as an app feature –  Associating a telephone number to app/service(s) •  Enhancing the call experience –  Adding Mobile Context to the call experience –  Unifying communications and related services –  Add ability to initiate, receive and control calls and other communication
  5. 5. Next Gen of Communication is Context-based “ T h e f u t u r e o f p e r s o n a l communications and computing is the mobile handset. Part of this future is the integration with local handset capabilities and sensors and the services on the web (the cloud). Part of this future is about leveraging the hidden information found in our actions and interactions, in our surroundings, in our mobile context.” Read more at
  6. 6. Enabling Voice on Android Apps •  Android provides Session Initiation Protocol (SIP) API; on Android 2.3+ •  Main classes: – SipManager defines the SIP API (Singleton) – SipProfile defines a SIP profile account (server, credentials, etc) – SipAudioCall handles an Internet audio call over SIP •  Also, BroadcastReceiver -- listener for incoming calls
  7. 7. Requirements •  Android 2.3 or higher •  Must have a SIP account •  SIP runs over a wireless data connection, so your device must have a data connection (with a mobile data service or Wi-Fi). – This means that you can't test on AVD—you can only test on a physical device.
  8. 8. Manifest <manifest xmlns:android="" package=""> <application android:icon="@drawable/icon" android:label="SipDemo"> <activity android:name=".SipActivity" android:configChanges="orientation|keyboardHidden"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> <receiver android:name=".IncomingCallReceiver" android:label="Call Receiver"/> </application> <uses-sdk android:minSdkVersion="9" /> <uses-permission android:name="android.permission.USE_SIP" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission.RECORD_AUDIO" /> <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> Request the INTERNET and USE_SIP permissions via Manifest.
  9. 9. public String sipAddress = null; public SipManager manager = null; public SipProfile me = null; public SipAudioCall call = null; public IncomingCallReceiver callReceiver; : @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout...); : // Set up the intent filter. This will be used to fire an // IncomingCallReceiver when someone calls the SIP address used // by this application. IntentFilter filter = new IntentFilter(); filter.addAction("android.SipDemo.INCOMING_CALL"); callReceiver = new IncomingCallReceiver(); this.registerReceiver(callReceiver, filter); if (manager == null) { manager = SipManager.newInstance(this); } } Initializing Set ContentView, Intent filter, get SipManager, …
  10. 10. try { SipProfile.Builder builder = new SipProfile.Builder(username, domain); builder.setPassword(password); builder.setOutboundProxy(outboundProxy); builder.setPort(port); builder.setProtocol(protocol); builder.setSendKeepAlive(true); me =; Intent i = new Intent(); i.setAction("android.SipDemo.INCOMING_CALL"); PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, Intent.FILL_IN_DATA);, pi, null); manager.setRegistrationListener(me.getUriString(), new SipRegistrationListener() { public void onRegistering(String localProfileUri) { ... } public void onRegistrationDone(String localProfileUri, long expiryTime) { ... } public void onRegistrationFailed(String localProfileUri, int errorCode, String errorMessage) { ... } } } catch (ParseException pe) { updateStatus("Connection Error."); } catch (SipException se) { updateStatus("Connection error."); } SIP Profile, Listening for Incoming Calls Set SIP Profile, set Incoming call intent, …
  11. 11. public class IncomingCallReceiver extends BroadcastReceiver { /** * Processes the incoming call, answers it, and hands it over to the * Activity. * @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(); } } }; : : } catch (Exception e) { if (incomingCall != null) { incomingCall.close(); } } } } Listening for Incoming Calls Incoming Call Receiver
  12. 12. Initiate Call public SipManager manager = null; public SipProfile me = null; : public void initiateCall() { try { 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 = manager.makeAudioCall(me.getUriString(), sipAddress, listener, 30); } catch (Exception e) { ... } } Incoming Call Receiver
  13. 13. Good Practices •  Call SipManager.isVoipSupported() to verify that the device supports VOIP calling •  Call SipManager.isApiSupported() to verify that the device supports the SIP APIs.
  14. 14. Thank You •  C. Enrique Ortiz •  Email: •  Twitter: @eortiz •  Website: •  Blog: •  Kloc:
  15. 15. About C. Enrique Ortiz •  Long-time Mobilist who focuses new Products, Technology & Innovation in the areas of Mobile, Cloud platforms and APIs •  Author: J2ME/MIDP (2001) and Android in Action (2011) and dozens of articles and presentations •  Organizer of Mobile Monday Austin, Android Dev Austin, and other