Enable push notifications for calls
Here, we'll learn how to enable push notifications for Azure Communication Services calls. Setting these up will let your users know when they have an incoming call which they can then answer.
Prerequisites
- An Azure account with an active subscription. Create an account for free.
- A deployed Communication Services resource. Create a Communication Services resource.
- A user access token to enable the calling client. For more information, see Create and manage access tokens.
- Optional: Complete the quickstart to add voice calling to your application
ACS Web Calling SDK - Web push notifications quickstart
Important
This feature of Azure Communication Services is currently in preview.
Preview APIs and SDKs are provided without a service-level agreement. We recommend that you don't use them for production workloads. Some features might not be supported, or they might have constrained capabilities.
For more information, review Supplemental Terms of Use for Microsoft Azure Previews.
ACS Web Calling SDK - Web push notifications are in public preview and available as part of version 1.12.0-beta.2+.
Please visit our web push notifications quickstart tutorial: https://github.com/Azure-Samples/communication-services-javascript-quickstarts/blob/main/calling-web-push-notifications/README.md
Install the SDK
Locate your project level build.gradle and make sure to add mavenCentral()
to the list of repositories under buildscript
and allprojects
buildscript {
repositories {
...
mavenCentral()
...
}
}
allprojects {
repositories {
...
mavenCentral()
...
}
}
Then, in your module level build.gradle add the following lines to the dependencies section
dependencies {
...
implementation 'com.azure.android:azure-communication-calling:1.0.0'
...
}
Initialize the required objects
To create a CallAgent
instance you have to call the createCallAgent
method on a CallClient
instance. This asynchronously returns a CallAgent
instance object.
The createCallAgent
method takes a CommunicationUserCredential
as an argument, which encapsulates an access token.
To access the DeviceManager
, a callAgent instance must be created first, and then you can use the CallClient.getDeviceManager
method to get the DeviceManager.
String userToken = '<user token>';
CallClient callClient = new CallClient();
CommunicationTokenCredential tokenCredential = new CommunicationTokenCredential(userToken);
android.content.Context appContext = this.getApplicationContext(); // From within an Activity for instance
CallAgent callAgent = callClient.createCallAgent(appContext, tokenCredential).get();
DeviceManager deviceManager = callClient.getDeviceManager(appContext).get();
To set a display name for the caller, use this alternative method:
String userToken = '<user token>';
CallClient callClient = new CallClient();
CommunicationTokenCredential tokenCredential = new CommunicationTokenCredential(userToken);
android.content.Context appContext = this.getApplicationContext(); // From within an Activity for instance
CallAgentOptions callAgentOptions = new CallAgentOptions();
callAgentOptions.setDisplayName("Alice Bob");
DeviceManager deviceManager = callClient.getDeviceManager(appContext).get();
CallAgent callAgent = callClient.createCallAgent(appContext, tokenCredential, callAgentOptions).get();
Additional Prerequisites for Push Notifications
A Firebase account set up with Cloud Messaging (FCM) enabled and with your Firebase Cloud Messaging service connected to an Azure Notification Hub instance. See Communication Services notifications for more information. Additionally, the tutorial assumes you're using Android Studio version 3.6 or higher to build your application.
A set of permissions is required for the Android application in order to be able to receive notifications messages from Firebase Cloud Messaging. In your AndroidManifest.xml
file, add the following set of permissions right after the <manifest ...>
or below the </application>
tag.
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
Overview
Mobile push notifications are the pop-up notifications you see on mobile devices. For calling, we'll be focusing on VoIP (Voice over Internet Protocol) push notifications. We'll register for push notifications, handle push notifications, and then un-register push notifications.
Register for push notifications
To register for push notifications, the application needs to call registerPushNotification()
on a CallAgent
instance with a device registration token.
To obtain the device registration token, add the Firebase SDK to your application module's build.gradle
file by adding the following lines in the dependencies
section if it's not already there:
// Add the SDK for Firebase Cloud Messaging
implementation 'com.google.firebase:firebase-core:16.0.8'
implementation 'com.google.firebase:firebase-messaging:20.2.4'
In your project level's build.gradle file, add the following in the dependencies
section if it's not already there:
classpath 'com.google.gms:google-services:4.3.3'
Add the following plugin to the beginning of the file if it's not already there:
apply plugin: 'com.google.gms.google-services'
Select Sync Now in the toolbar. Add the following code snippet to get the device registration token generated by the Firebase Cloud Messaging SDK for the client application instance Be sure to add the below imports to the header of the main Activity for the instance. They're required for the snippet to retrieve the token:
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.iid.FirebaseInstanceId;
import com.google.firebase.iid.InstanceIdResult;
Add this snippet to retrieve the token:
FirebaseInstanceId.getInstance().getInstanceId()
.addOnCompleteListener(new OnCompleteListener<InstanceIdResult>() {
@Override
public void onComplete(@NonNull Task<InstanceIdResult> task) {
if (!task.isSuccessful()) {
Log.w("PushNotification", "getInstanceId failed", task.getException());
return;
}
// Get new Instance ID token
String deviceToken = task.getResult().getToken();
// Log
Log.d("PushNotification", "Device Registration token retrieved successfully");
}
});
Register the device registration token with the Calling Services SDK for incoming call push notifications:
String deviceRegistrationToken = "<Device Token from previous section>";
try {
callAgent.registerPushNotification(deviceRegistrationToken).get();
}
catch(Exception e) {
System.out.println("Something went wrong while registering for Incoming Calls Push Notifications.")
}
Push notification handling
To receive incoming call push notifications, call handlePushNotification() on a CallAgent instance with a payload.
To obtain the payload from Firebase Cloud Messaging, begin by creating a new Service (File > New > Service > Service) that extends the FirebaseMessagingService Firebase SDK class and override the onMessageReceived
method. This method is the event handler called when Firebase Cloud Messaging delivers the push notification to the application.
public class MyFirebaseMessagingService extends FirebaseMessagingService {
private java.util.Map<String, String> pushNotificationMessageDataFromFCM;
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
// Check if message contains a notification payload.
if (remoteMessage.getNotification() != null) {
Log.d("PushNotification", "Message Notification Body: " + remoteMessage.getNotification().getBody());
}
else {
pushNotificationMessageDataFromFCM = remoteMessage.getData();
}
}
}
Add the following service definition to the AndroidManifest.xml
file, inside the <application>
tag:
<service
android:name=".MyFirebaseMessagingService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
- Once the payload is retrieved, it can be passed to the Communication Services SDK to be parsed out into an internal IncomingCallInformation object that will be handled by calling the handlePushNotification method on a CallAgent instance. A
CallAgent
instance is created by calling thecreateCallAgent(...)
method on theCallClient
class.
try {
IncomingCallInformation notification = IncomingCallInformation.fromMap(pushNotificationMessageDataFromFCM);
Future handlePushNotificationFuture = callAgent.handlePushNotification(notification).get();
}
catch(Exception e) {
System.out.println("Something went wrong while handling the Incoming Calls Push Notifications.");
}
When the handling of the Push notification message is successful, and the all events handlers are registered properly, the application will ring.
Unregister push notifications
Applications can unregister push notification at any time. Call the unregisterPushNotification()
method on callAgent to unregister.
try {
callAgent.unregisterPushNotification().get();
}
catch(Exception e) {
System.out.println("Something went wrong while un-registering for all Incoming Calls Push Notifications.")
}
Set up your system
Create the Xcode project
In Xcode, create a new iOS project and select the Single View App template. This quickstart uses the SwiftUI framework, so you should set the Language to Swift and User Interface to SwiftUI.
You're not going to create unit tests or UI tests during this quickstart. Feel free to clear the Include Unit Tests and Include UI Tests text boxes.
Install the package and dependencies with CocoaPods
Create a Podfile for your application, like this:
platform :ios, '13.0' use_frameworks! target 'AzureCommunicationCallingSample' do pod 'AzureCommunicationCalling', '~> 1.0.0' end
Run
pod install
.Open
.xcworkspace
with Xcode.
Request access to the microphone
To access the device's microphone, you need to update your app's information property list with NSMicrophoneUsageDescription
. You set the associated value to a string
that will be included in the dialog that the system uses to request access from the user.
Right-click the Info.plist
entry of the project tree and select Open As > Source Code. Add the following lines in the top-level <dict>
section, and then save the file.
<key>NSMicrophoneUsageDescription</key>
<string>Need microphone access for VOIP calling.</string>
Set up the app framework
Open your project's ContentView.swift file and add an import
declaration to the top of the file to import the AzureCommunicationCalling
library. In addition, import AVFoundation
. You'll need it for audio permission requests in the code.
import AzureCommunicationCalling
import AVFoundation
Initialize CallAgent
To create a CallAgent
instance from CallClient
, you have to use a callClient.createCallAgent
method that asynchronously returns a CallAgent
object after it's initialized.
To create a call client, you have to pass a CommunicationTokenCredential
object.
import AzureCommunication
let tokenString = "token_string"
var userCredential: CommunicationTokenCredential?
do {
let options = CommunicationTokenRefreshOptions(initialToken: token, refreshProactively: true, tokenRefresher: self.fetchTokenSync)
userCredential = try CommunicationTokenCredential(withOptions: options)
} catch {
updates("Couldn't created Credential object", false)
initializationDispatchGroup!.leave()
return
}
// tokenProvider needs to be implemented by Contoso, which fetches a new token
public func fetchTokenSync(then onCompletion: TokenRefreshOnCompletion) {
let newToken = self.tokenProvider!.fetchNewToken()
onCompletion(newToken, nil)
}
Pass the CommunicationTokenCredential
object that you created to CallClient
, and set the display name.
self.callClient = CallClient()
let callAgentOptions = CallAgentOptions()
options.displayName = " iOS Azure Communication Services User"
self.callClient!.createCallAgent(userCredential: userCredential!,
options: callAgentOptions) { (callAgent, error) in
if error == nil {
print("Create agent succeeded")
self.callAgent = callAgent
} else {
print("Create agent failed")
}
})
Set up push notifications
A mobile push notification is the pop-up notification that you get in the mobile device. For calling, we'll focus on VoIP (voice over Internet Protocol) push notifications.
The following sections describe how to register for, handle, and unregister push notifications. Before you start those tasks, complete these prerequisites:
- In Xcode, go to Signing & Capabilities. Add a capability by selecting + Capability, and then select Push Notifications.
- Add another capability by selecting + Capability, and then select Background Modes.
- Under Background Modes, select the Voice over IP and Remote notifications checkboxes.
Register for push notifications
To register for push notifications, call registerPushNotification()
on a CallAgent
instance with a device registration token.
Registration for push notifications needs to happen after successful initialization. When the callAgent
object is destroyed, logout
will be called, which will automatically unregister push notifications.
let deviceToken: Data = pushRegistry?.pushToken(for: PKPushType.voIP)
callAgent.registerPushNotifications(deviceToken: deviceToken!) { (error) in
if(error == nil) {
print("Successfully registered to push notification.")
} else {
print("Failed to register push notification.")
}
}
Handle push notifications
To receive push notifications for incoming calls, call handlePushNotification()
on a CallAgent
instance with a dictionary payload.
let callNotification = PushNotificationInfo.fromDictionary(pushPayload.dictionaryPayload)
callAgent.handlePush(notification: callNotification) { (error) in
if (error == nil) {
print("Handling of push notification was successful")
} else {
print("Handling of push notification failed")
}
}
Unregister push notifications
Applications can unregister push notification at any time. Simply call the unregisterPushNotification
method on CallAgent
.
Note
Applications are not automatically unregistered from push notifications on logout.
callAgent.unregisterPushNotification { (error) in
if (error == nil) {
print("Unregister of push notification was successful")
} else {
print("Unregister of push notification failed, please try again")
}
}
Next steps
Feedback
Submit and view feedback for