Push notifications Android
Working in background
One of key features of VoIP SIP client is ability to receive incoming calls. It requires to maintain signaling connection with SIP Server (PBX). This approach is good for desktop applications, but quite complicated for mobile. New Android versions heavily restricts running and use network when application is in the background mode.
Possible solutions:
Run SDKs service in foreground mode.
[+] It allows to work in the background, maintain connection with SIP Server, display notification when incoming call received.
[+] Doesn’t require any specific configuration on server side.
[-] It’s not 100% reliable, system may stop it in any time.
[-] It drains battery of the device.
Use push notifications
[+] It’s recommended approach.
[+] Allows application to run only when it’s required, which prevents battery drain.
[-] Requires a bit more complicated implementation.
[-] Requires specific configuration of the SIP Server (PBX).
Run SDKs service in foreground mode
In case of using Flutter add this line of code after initialization
await SiprixVoipSdk().setForegroundMode(true);
Receiving incoming calls
SIP incoming call on client side starts from receiving INVITE request, which in turn,
requires valid connection with SIP Server (PBX).
It follows, that reason of issues with receiving incoming calls are:
App is not running.
App is running in background and can’t access network.
App hadn’t refreshed registration after switch from one of previous states
When library received INVITE request it raises ISiprixEventHandler::OnCallIncoming().
This event is handling depending on the application’s state.
When app is in background it can’t start activity and has to display local notification.
When app is in foreground it can just update UI and display newly received call.
Adding and handling push notifications in native Android apps
Send push token along with
REGISTERrequestUse
FirebaseMessaging.getInstance().getToken()to retrive tokenSend this token as separate header or ContactUri Param.
As example see Flutter and SampleJava example of implementation:
Configure SIP Server (PBX)
Before forward call to client PBX should check had it provided push token. When token found - send push message to that client, wait a bit (let client to receive message and restore/refresh registration) and only after that forward
INVITErequest or report error.Handle received message
When Android application receives push message it should:
Create library instance (if it doesn’t exist) and update registration (if required).
Wait incoming call and handle it as explained above.
Important
FCM has two types of messages: data and notification messages. Application handles both of them in the method
FirebaseMessagingService::onMessageReceived.Notification messages are handled in this method only when app is in the foreground. When app is in the background an automatically generated notification is displayed.
Data messages (recommended for VoIP apps) are handled whether the app is in the foreground or background. We suggest to use only this type of messages. Example of data message see here:
Messages containing both notification and data payloads are treated as notification messages. For more see: About FCM messages.
State diagram of handling Android push notifications
Diagram below has 2 entry points (yellow rectangles):
onCreate- activated each time when user starts main activity.
onMessageReceived- activated when received firebase message.
Both these points starting CallNotifService, which in turn verifies current state and if required: initializes library, gets push token, restores saved accounts and updates registration. On the diagram this pattern highlighted by dotted green border.
Create a Firebase Project
Go to the Firebase Console.
Click on Add Project
Follow the setup wizard to create a new Firebase project
Click
+ Add app, selectAndroidicon, enter application’s package name and nickname, download google-services.json. Copy downloaded file to the theapp/directory of your project (for native Java/Kotlin projects).
Sending push notification
Sending push notifications with FCM should be implemented on SIP Server side and should include authorization as explained here: Authorize send requests.
Often enough is required to quickly test how app handles FCM push notifications and not necessarily you want create a whole back-end infrastructure.
You can use the Google Developers OAuth 2.0 Playground and here is short manual how to do that:
Visit the OAuth Playground.
Select & authorize APIs
In the edit box
Input your scopesenterhttps://www.googleapis.com/auth/firebase.messagingand click ‘[Authorize APIs]’ as shown on image:.
On next page select the Google account associated with your Firebase project and grant permissions to authorize the OAuth flow
Exchange authorization code for tokens
Click button [Exchange authorization code for tokens] as shown on image:
.
Configure request to API
Switch HTTP method to
POSTIn the edit box
Request URIenterhttps://fcm.googleapis.com/v1/projects/YOUR_PROJECT/messages:sendas shown on image:Enter request body (builds data message) as shown on image:
{ "message": { "token": "dUa4FSUaT...xsR8", "data": { "kFrom": "FromX", "Key2": "val2"}, "android":{ "ttl":"30s", "priority":"high" } } }
where:
token - token of the device;
data - any data which app may use for its own purposes;
ttl - time_to_live value in seconds. How long FCM should hold the notification if the device is unreachable. ;
priority - priority of the notification. “High” allows to start background service, which will restore registration and receive incoming call;
Send the request