WebsiteBeaver / CordovaCall

Cordova CallKit & ConnectionService plugin for iOS/Android that displays the native call UI for VOIP apps
MIT License
197 stars 92 forks source link

Cordova Call

Install

Add the CordovaCall plugin to your Cordova project

cordova plugin add cordova-call

Examples

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;
});

Receive A Phone Call

cordova.plugins.CordovaCall.receiveCall('David Marcus');

CordovaCall Receive Call iOS CallKit CordovaCall Receive Call ConnectionService

Once you press Accept on iOS or you Swipe up to answer on Android, you'll see the in-call UI:

CordovaCall Answer Call iOS CallKit CordovaCall Answer Call Android ConnectionService

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.

CordovaCall All calling accounts Android ConnectionService CordovaCall Accept Phone Account Android ConnectionService

Send A Phone Call

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:

CordovaCall Send Call iOS CallKit CordovaCall Send Call Android ConnectionService

After 5 seconds pass, you'll notice that the screen changes because of the connectCall function:

CordovaCall Connect Call iOS CallKit CordovaCall Connect Call Android ConnectionService

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.

Make A Call From Recents

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.

CordovaCall IncludeInRecents iOS CallKit CordovaCall IncludeInRecents Social Profile iOS CallKit

Use A Title Different Than App Name

cordova.plugins.CordovaCall.setAppName('New App Name');
cordova.plugins.CordovaCall.receiveCall('David Marcus');

CordovaCall Change App Name iOS CallKit CordovaCall Change App Name Android ConnectionService

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.

Use Your Custom Logo

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="https://github.com/WebsiteBeaver/CordovaCall/raw/master/beaver.png" target="res/drawable/beaver.png" />
</platform>
<platform name="ios">
    <resource-file src="https://github.com/WebsiteBeaver/CordovaCall/raw/master/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');

CordovaCall Custom Icon iOS CallKit CordovaCall Custom Icon Android ConnectionService

How awesome is that! You can use your own logo to make your VOIP app be more official.

Make It Say Video Instead Of Audio

cordova.plugins.CordovaCall.setVideo(true);
cordova.plugins.CordovaCall.receiveCall('David Marcus');
CordovaCall Video Instead Of Audio iOS CallKit

This is an iOS only feature. You should use this if your app supports video chat.

Change The Ringtone

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="https://github.com/WebsiteBeaver/CordovaCall/raw/master/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:

CordovaCall Custom Ringtone

Documentation

Functions

receiveCall

cordova.plugins.CordovaCall.receiveCall(from [, id] [, success] [, error]);

Support: iOS 10+ and Android Marshmallow+

sendCall

cordova.plugins.CordovaCall.sendCall(to [, id] [, success] [, error]);

Support: iOS 10+ and Android Marshmallow+

connectCall

cordova.plugins.CordovaCall.connectCall([, success] [, error]);

Support: iOS 10+ and Android Marshmallow+

endCall

cordova.plugins.CordovaCall.endCall([, success] [, error]);

Support: iOS 10+ and Android Marshmallow+

mute

cordova.plugins.CordovaCall.mute([, success] [, error]);

Support: Android Marshmallow+

unmute

cordova.plugins.CordovaCall.unmute([, success] [, error]);

Support: Android Marshmallow+

speakerOn

cordova.plugins.CordovaCall.speakerOn([, success] [, error]);

Support: iOS 10+ and Android Marshmallow+

speakerOff

cordova.plugins.CordovaCall.speakerOff([, success] [, error]);

Support: iOS 10+ and Android Marshmallow+

callNumber

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.

Options

setAppName

cordova.plugins.CordovaCall.setAppName(appName [, success] [, error]);

Support: iOS 10+ and Android Marshmallow+

setIcon

cordova.plugins.CordovaCall.setIcon(iconName [, success] [, error]);

Support: iOS 10+ and Android Marshmallow+

setVideo

cordova.plugins.CordovaCall.setVideo(value [, success] [, error]);

Support: iOS 10+

setRingtone

cordova.plugins.CordovaCall.setRingtone(ringtoneName [, success] [, error]);

Support: iOS 10+

setIncludeInRecents

cordova.plugins.CordovaCall.setIncludeInRecents(value [, success] [, error]);

Support: iOS 11+

setDTMFState

cordova.plugins.CordovaCall.setDTMFState(value [, success] [, error]);

Support: iOS 10+

Events

onAnswer

cordova.plugins.CordovaCall.on('answer', handler);

Support: iOS 10+ and Android Marshmallow+

onHangup

cordova.plugins.CordovaCall.on('hangup', handler);

Support: iOS 10+ and Android Marshmallow+

onReject

cordova.plugins.CordovaCall.on('reject', handler);

Support: iOS 10+ and Android Marshmallow+

onReceiveCall

cordova.plugins.CordovaCall.on('receiveCall', handler);

Support: iOS 10+ and Android Marshmallow+

onSendCall

cordova.plugins.CordovaCall.on('sendCall', handler);

Support: iOS 10+ and Android Marshmallow+

onMute

cordova.plugins.CordovaCall.on('mute', handler);

Support: iOS 10+

onUnmute

cordova.plugins.CordovaCall.on('unmute', handler);

Support: iOS 10+

onSpeakerOn

cordova.plugins.CordovaCall.on('speakerOn', handler);

Support: iOS 10+

onSpeakerOff

cordova.plugins.CordovaCall.on('speakerOff', handler);

Support: iOS 10+

onDTMF

cordova.plugins.CordovaCall.on('DTMF', handler);

Support: iOS 10+

Common Errors

Info.plist

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.

  1. Required background modes with type Array and value App provides Voice over IP services.
  2. NSUserActivityTypes with type Array and two items with type String: INStartAudioCallIntent and INStartVideoCallIntent
Info.plist

About

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.

Built With

License

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.