Add the CordovaCall plugin to your Cordova project
cordova plugin add cordova-call
Once you install the CordovaCall plugin, it's very easy to get started. Take a look at some of these examples to get a feel for using this plugin. Note that you should place the functions in onDeviceReady
as specified in the Cordova docs. The screenshots used in these examples show iOS 11 on an iPhone 7 (left) and Android Oreo on a Google Pixel (right). Because CallKit doesn't work on the simulator, you'll need to run this plugin on an actual iOS device (iOS 10 or greater). The one exception is the sendCall
function which works on the simulator. CordovaCall works well on the Android Emulator (assuming you have Marshmallow or greater). These examples are meant to be simple, but make sure that in production you call functions within the callbacks to ensure that one finishes before you start another.
//Vanilla JavaScript
document.addEventListener('deviceready', function() {
console.log('cordova.plugins.CordovaCall is now available');
var cordovaCall = cordova.plugins.CordovaCall; //not necessary, but might be more convenient
});
//jQuery-like (ex: DOM7)
$$(document).on('deviceready', function() {
console.log('cordova.plugins.CordovaCall is now available');
var cordovaCall = cordova.plugins.CordovaCall;
});
cordova.plugins.CordovaCall.receiveCall('David Marcus');
Once you press Accept on iOS or you Swipe up to answer on Android, you'll see the in-call UI:
If you're using WebRTC to make a video or audio chat app, you can call receiveCall
right before pc.setRemoteDescription
. For an excellent explanation of how to use WebRTC check out this WebsiteBeaver tutorial.
The first time you run this function on Android, you'll be taken to a screen that says Calling accounts. You have to click on All calling accounts
and then click on the switch as shown below. On Android Oreo and above this doesn't happen anymore 😃 The Calling accounts
screen gets skipped, and the native call UI is shown immediately.
cordova.plugins.CordovaCall.sendCall('Daniel Marcus');
//simulate your friend answering the call 5 seconds after you call
setTimeout(function(){
cordova.plugins.CordovaCall.connectCall();
}, 5000);
You'll see a screen that shows that your call is being connected as show below:
After 5 seconds pass, you'll notice that the screen changes because of the connectCall
function:
If you're using WebRTC, you might call pc.createOffer
in the success callback of sendCall
. The best place to call connectCall
is in pc.onaddstream
.
Note: In iOS, CallKit does not provide a UI when creating a call via sendCall
. Your app should handle this by providing an 'in-call' UI. This UI can be accessed from within the incoming call connected UI provided by CallKit by clicking on the provider app icon setIcon
.
cordova.plugins.CordovaCall.setIncludeInRecents(true);
cordova.plugins.CordovaCall.receiveCall('David Marcus',21);
cordova.plugins.CordovaCall.on('sendCall',function(info){
//info now contains the user id of the person you're trying to call
setTimeout(function(){
cordova.plugins.CordovaCall.connectCall();
}, 5000);
});
This only works on iOS 11, and not with Android. It's a really neat feature, so props to Apple for adding this. If you call setIncludeInRecents
, and pass in true as the parameter, calls get stored in Recents. By default calls do not get stored in Recents. Once you tap on the info icon to the right of David Marcus, you'll see the screen on the right. You can set the Social profile to whatever you like (user id is a good choice for many apps that store user ids and names in a database). If you don't set the Social profile, it gets set to the person's name by default. The coolest part about this is that you can call the person back just like a regular phone call. If you use the code in this example, info will contain the user id (21 in this example). This way you can link user ids to names.
cordova.plugins.CordovaCall.setAppName('New App Name');
cordova.plugins.CordovaCall.receiveCall('David Marcus');
Say you name your app something. It will show up as the title by default with CordovaCall. If you'd like to change the text that shows up without renaming your app, this is an easy way to accomplish that. As you can see above, the app name hasn't changed, but the title that shows up has. Note that after you use this function, Android will force you to go through the Calling accounts screen again before you can receive and send phone calls.
Start by adding your icon to your app directory (the same location for config.xml
, www
, and plugins
). You should select a 120px x 120px image. It should have transparency. This example uses a beaver icon found on Icons8.
Next you need to add resource-file tags to your config.xml
(substitute beaver with whatever you named your image). There will already be two platform tags (one for android and one for ios), so just insert the resource-file tags in the platform tags as show here:
<platform name="android">
<resource-file src="beaver.png" target="res/drawable/beaver.png" />
</platform>
<platform name="ios">
<resource-file src="beaver.png" />
</platform>
Run cordova build ios
followed by cordova build android
. At this point, you're ready to change the call icon and receive a phone call.
cordova.plugins.CordovaCall.setIcon('beaver');
cordova.plugins.CordovaCall.receiveCall('David Marcus');
How awesome is that! You can use your own logo to make your VOIP app be more official.
cordova.plugins.CordovaCall.setVideo(true);
cordova.plugins.CordovaCall.receiveCall('David Marcus');
This is an iOS only feature. You should use this if your app supports video chat.
This only works on iOS. Make sure to add a custom ringtone file to your app directory (the same location for config.xml
, www
, and plugins
). The ringtone should be a .caf
file.
<platform name="ios">
<resource-file src="ringtone.caf" />
</platform>
Run cordova build ios
. Now call the setRingtone
function.
cordova.plugins.CordovaCall.setRingtone('ringtone');
cordova.plugins.CordovaCall.receiveCall('David Marcus');
Click the iPhone below to see and hear an example of receiving a call with a custom ringtone:
cordova.plugins.CordovaCall.receiveCall(from [, id] [, success] [, error]);
Support: iOS 10+ and Android Marshmallow+
- from
Type: String
The name of the person you want to get a call from - id
Type: Integer
The user id that allows you to identify the person's name - success
Type: Function
A callback that gets executed if the incoming call is successful - error
Type: Function
A callback that gets executed if the incoming call fails
cordova.plugins.CordovaCall.sendCall(to [, id] [, success] [, error]);
Support: iOS 10+ and Android Marshmallow+
- to
Type: String
The name of the person you want to call - id
Type: Integer
The user id that allows you to identify the person's name - success
Type: Function
A callback that gets executed if the outgoing call is successful - error
Type: Function
A callback that gets executed if the outgoing call fails
cordova.plugins.CordovaCall.connectCall([, success] [, error]);
Support: iOS 10+ and Android Marshmallow+
- success
Type: Function
A callback that gets executed if the outgoing call gets connected successfully - error
Type: Function
A callback that gets executed if the outgoing call fails to connect
cordova.plugins.CordovaCall.endCall([, success] [, error]);
Support: iOS 10+ and Android Marshmallow+
- success
Type: Function
A callback that gets executed if the call ends successfully - error
Type: Function
A callback that gets executed if the call fails to end
cordova.plugins.CordovaCall.mute([, success] [, error]);
Support: Android Marshmallow+
- success
Type: Function
A callback that gets executed if the call gets muted successfully - error
Type: Function
A callback that gets executed if the call fails to mute
cordova.plugins.CordovaCall.unmute([, success] [, error]);
Support: Android Marshmallow+
- success
Type: Function
A callback that gets executed if the call gets unmuted successfully - error
Type: Function
A callback that gets executed if the call fails to unmute
cordova.plugins.CordovaCall.speakerOn([, success] [, error]);
Support: iOS 10+ and Android Marshmallow+
- success
Type: Function
A callback that gets executed if the speakerphone gets turned on - error
Type: Function
A callback that gets executed if the speakerphone fails to turn on
cordova.plugins.CordovaCall.speakerOff([, success] [, error]);
Support: iOS 10+ and Android Marshmallow+
- success
Type: Function
A callback that gets executed if the speakerphone gets turned off - error
Type: Function
A callback that gets executed if the speakerphone fails to turn off
cordova.plugins.CordovaCall.callNumber(to [, success] [, error]);
Support: iOS 2+ and Android Cupcake+
This is the only function that isn't related to VOIP, as it strictly deals with phone calls.
- to
Type: String
The number of the person you want to call (for example 5618770325). Note that this function will actually try to make a real phone call, and is not meant for voip apps. - success
Type: Function
A callback that gets executed if the phone call is successful - error
Type: Function
A callback that gets executed if the phone call fails
cordova.plugins.CordovaCall.setAppName(appName [, success] [, error]);
Support: iOS 10+ and Android Marshmallow+
- appName
Type: String
The title of the call which is your app name by default - success
Type: Function
A callback that gets executed if the title gets changed successfully - error
Type: Function
A callback that gets executed if the title fails to change
cordova.plugins.CordovaCall.setIcon(iconName [, success] [, error]);
Support: iOS 10+ and Android Marshmallow+
- iconName
Type: String
The file name (should be a .png file) of the icon you'd like displayed during a call. You need to add the file to your project's directory next to config.xml, platforms, plugins, etc. Then you have to add resource tags to your config.xml file. Finally, make sure to build your project. Take a look at Use Your Custom Logo for a complete example. - success
Type: Function
A callback that gets executed if the icon gets changed successfully - error
Type: Function
A callback that gets executed if the icon fails to change
cordova.plugins.CordovaCall.setVideo(value [, success] [, error]);
Support: iOS 10+
- value
Type: Boolean
Set this to true if you want the call to show up as a video call. By default or if you call this function with a value of false, the call will show up as an audio call. - success
Type: Function
A callback that gets executed if the video type gets changed successfully - error
Type: Function
A callback that gets executed if the video type fails to change
cordova.plugins.CordovaCall.setRingtone(ringtoneName [, success] [, error]);
Support: iOS 10+
- iconName
Type: String
The file name (should be a .caf file) of the ringtone you'd like played during a call. You need to add the file to your project's directory next to config.xml, platforms, plugins, etc. Then you have to add resource tags to your config.xml file. Finally, make sure to build your project. Take a look at Change The Ringtone for a complete example. - success
Type: Function
A callback that gets executed if the ringtone gets changed successfully - error
Type: Function
A callback that gets executed if the ringtone fails to change
cordova.plugins.CordovaCall.setIncludeInRecents(value [, success] [, error]);
Support: iOS 11+
- value
Type: Boolean
Set this to true if you want calls to show up in recent calls. By default it won't show up in recents if you're using iOS 11. If you're using iOS 10, by default it will show up in recents (and you can't call this function to prevent it from showing up in recents). - success
Type: Function
A callback that gets executed if the recent calls preference gets changed successfully - error
Type: Function
A callback that gets executed if the recent calls preference fails to change
cordova.plugins.CordovaCall.setDTMFState(value [, success] [, error]);
Support: iOS 10+
- value
Type: Boolean
Set this to true/false to enable/disable DTMF usage. - success
Type: Function
A callback that gets executed if DTMF setState changed successfully - error
Type: Function
A callback that gets executed if the DTMF setState fails to change
cordova.plugins.CordovaCall.on('answer', handler);
Support: iOS 10+ and Android Marshmallow+
- handler
Type: Function
A user-defined function that gets executed when you answer an incoming call
cordova.plugins.CordovaCall.on('hangup', handler);
Support: iOS 10+ and Android Marshmallow+
- handler
Type: Function
A user-defined function that gets executed when you hangup a call
cordova.plugins.CordovaCall.on('reject', handler);
Support: iOS 10+ and Android Marshmallow+
- handler
Type: Function
A user-defined function that gets executed when you reject an incoming call
cordova.plugins.CordovaCall.on('receiveCall', handler);
Support: iOS 10+ and Android Marshmallow+
- handler
Type: Function
A user-defined function that gets executed when you receive a call
cordova.plugins.CordovaCall.on('sendCall', handler);
Support: iOS 10+ and Android Marshmallow+
- handler
Type: Function
A user-defined function that gets executed when you send a call. You can use the data that gets returned in the handler to access the user id that corresponds to the callee's name. This is very useful if you make a call from recents, and need to get the call information.
cordova.plugins.CordovaCall.on('mute', handler);
Support: iOS 10+
- handler
Type: Function
A user-defined function that gets executed when you press the mute button on the native call UI. Note that it does not trigger if you call the mute function.
cordova.plugins.CordovaCall.on('unmute', handler);
Support: iOS 10+
- handler
Type: Function
A user-defined function that gets executed when you press the unmute button on the native call UI. Note that it does not trigger if you call the unmute function.
cordova.plugins.CordovaCall.on('speakerOn', handler);
Support: iOS 10+
- handler
Type: Function
A user-defined function that gets executed when you press the speakerOn button on the native call UI, and when you call the speakerOn function.
cordova.plugins.CordovaCall.on('speakerOff', handler);
Support: iOS 10+
- handler
Type: Function
A user-defined function that gets executed when you press the speakerOff button on the native call UI, and when you call the speakerOff function.
cordova.plugins.CordovaCall.on('DTMF', handler);
Support: iOS 10+
- handler
Type: Function
A user-defined function that gets executed when you press the DTMF buttons on the DTMF native call UI and returns a string with the digit pressed.
If you get an error that says The operation couldn’t be completed. (com.apple.CallKit.error.requesttransaction error 1.)
, open up your .xcworkspace
file in Xcode, and modify the Info.plist file. You need to add two keys. These keys should already be in your Info.plist because they get added when you install CordovaCall, but you might have deleted them.
Required background modes
with typeArray
and valueApp provides Voice over IP services
.NSUserActivityTypes
with typeArray
and two items with typeString
:INStartAudioCallIntent
andINStartVideoCallIntent
Use this Cordova plugin to make your VOIP (audio and video calling) apps feel more native by having calls within your app appear like regular phone calls. You can display the incoming call screen and outgoing call screen by simply calling a JavaScript function. Ringtone sound, call icon, and several other features can be customized. This plugin takes advantage of iOS CallKit and Android ConnectionService in order to allow you to give your app users a better experience by having audio and video calls from your app appear like regular phone calls. WebRTC goes very well with this plugin.
- Cordova - Allows you to write JavaScript in order to make apps for iOS, Android, etc.
- CallKit - iOS Framework that allows your app to access the native call UI
- ConnectionService - Android class that allows your app to access the native call UI
MIT License
Copyright (c) 2017 David Marcus
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.