Getting Started with Android Facade¶
Acrobits Facade SDK provides an easier way to interact with the native libSoftphone SDK. Facade SDK enables the most complex features such as the SDK setup, lifecycle registration, or calls to be handled automatically.
This section describes the steps to create a simple Android application using Facade SDK.
Installing Facade SDK¶
Ensure the Android Studio installation is complete. Then, to add Facade SDK to the Android Gradle project:
Locate and open the project-level
build.gradle
file in the root directory of your Android project.Add Acrobits Maven repository in the repository block and include your application identifier and license key:
1maven { 2 url "https://maven.acrobits.net/repository/maven-releases/" 3 credentials { 4 <username> 5 <password> 6 } 7}Note
Replace
<username>
with your application identifier,<password>
with your license key.
<password>
, the license key, can be obtained from the portal after completing step 1 in the Quick Start Guide.We recommend using
dependencyResolutionManagement
to add the Maven repository.Add the libSoftphone dependency for the SDK in the application-level
build.gradle
file:1dependencies { 2 implementation 'cz.acrobits.libsoftphone:facade:<version>' 3}Note
Replace
<version>
with the version of the SDK.
Initializing the SDK¶
The setup process for Facade SDK is simpler compared to that of the native SDK. To initialize and prepare Facade SDK for operation, set up the SDK configuration and then the runtime.
Setting up the SDK Configuration¶
In general, you only have to set up the configuration once during the lifetime of your application process.
Note
Acrobits recommends you create a custom Application
class and run the setup upon calling the onCreate
method. The setup is fast as only a few constructors are called so the application startup time is not impacted.
Use the following configuration block to set up the SDK configuration. The configuration blocks follow a builder pattern and are not required to be in a specific order.
1SoftphoneFacade.create(
2 [ context ],
3 [ your license key ],
4 configuration -> configuration
5 .pushMessage(pushMessage -> {
6 // push messaging setup
7 })
8 .preferences(preferences -> preferences
9 // preferences setup
10 )
11 .account(account -> {
12 // account setup
13 })
14 .callbacks(callbacks -> {
15 // callbacks registration
16 })
17 .ui(ui -> {
18 // UI configuration
19 })
20 .notification(notification -> {
21 // notification configuration
22 })
23 );
Warning
The native methods of libSoftphone SDK are accessible only after calling the SoftphoneFacade.start()
method. One of the affected classes by this is the cz.acrobits.ali.Xml
class, which uses native code for fast parsing.
Note
The license key can be obtained in the Acrobits licensing portal after completing step 1 in the Quick Start Guide.
Developers should at least implement the push message push message and call assets blocks for the SDK to handle outgoing and incoming calls.
All configuration blocks are lazily evaluated only when they are needed by Facade SDK.
The following sections explain in more detail the individual blocks within this configuration block.
- The Push Message Block
Notifies the Facade SDK changes in push token and new push messages.
Go to the Incoming Calls Over Push section for more information to manage push notifications.
- The Preferences Block
Changes the default values of individual preference keys.
Example:
1preferences -> { 2 preferences.overrideDefault(prefs -> prefs.userAgentOverride, "Acrobits DemoPhone") 3}
Note
Preferences are also accessible when configuring the runtime.
Refer to the Managing Preferences section for more information.
- The Account Block
Configures the initial and default SIP account.
The account options are passed through
cz.acrobits.ali.Xml
.Note
The
cz.acrobits.ali.Xml
class uses native code to achieve fast parsing. However, the native methods are available only afterSoftphoneFacade.start()
is being called. Therefore, you need to construct thecz.acrobits.ali.Xml
object inside a lambda expression. This is because the lambda expression is evaluated lazily and is executed only whenSoftphoneFacade.start()
is called.Example:
1account -> { 2 // This is evaluated only after the native methods are loaded 3 4 Xml xml = new Xml("account"); 5 xml.setAttribute(Account.Attributes.ID, "Testing account"); 6 xml.setChildValue(Account.HOST, "example.com"); 7 account.set(xml); 8}
Note
Accounts are also accessible when configuring the runtime.
Refer to the Managing SIP Account section for more information on account management.
- The Callbacks Block
Registers listeners for SDK events.
Example:
1Set<Disposable> disposables = new HashSet(); 2 3... 4 5callbacks -> { 6 disposables.add(callbacks.registration(regState -> {})) 7}
Note
Accounts are also accessible when configuring the runtime.
Refer to the Call Assets Delegate section for more information on callbacks.
- The Call Assets Block
Manages the appearance of the active call screen, which refers to the user interface during a call. Provide Acrobits with all the assets for calls to enhance user experience.
Example:
1configuration.callAssets(new ExampleCallAssetsDelegate())
Refer to the Call Assets Delegate section for more information.
- The UI Block
Configures the behavior of elements on the active call screen.
Examples:
To customize the audio route option when the user presses the speaker button:
1ui.speakerButtonPolicy(new CustomSpeakerButtonPolicy());
CustomSpeakerButtonPolicy
implements theUiDelegate.SpeakerButtonPolicy
interface. By default, theCyclingSpeakerButtonPolicy
is used.The label on the incoming call screen displays the application name by default. To customize the label to display your brand name, pass the string to the
ui.brandName()
function:1ui.brandName("Your brand");
- The Notification Block
Customizes all displayed notifications.
Examples:
Facade SDK uses the default small icon as the app icon for all notifications. To override with another drawable icon, pass it to the
notification.defaultSmallIcon
function:1notification.defaultSmallIcon(R.drawable.your_small_icon);
To customize the individual notifications, pass the drawable resources specific that is to a desired context and communication channel to the
notification.inCallTemplate
function:1notification.inCallTemplate((context, channelId) -> { 2 NotificationCompat.Builder builder = new NotificationCompat.Builder(context, channelId); 3 builder.setSmallIcon(R.drawable.your_small_icon); 4 return builder; 5});
Warning
This might cause Facade SDK to simultaneously override multiple notification properties.
SDK Lifecycle¶
Facade SDK has its own lifecycle, which can be gotten through .getLifecycle()
, and transitions through the following states:
Initialized - the initial state, Facade is ready to be started.
Stopped - Facade stops. Do not start it yet.
Running - Facade is fully initialized and started.
Setting up the Runtime¶
After setting up the configuration, start Facade SDK by transitioning it from Initialized to Running.
Call
.start()
to activate Facade SDK based on the configuration.Note
Reporting a push remote message to an Initialized Facade instance invokes
.start()
.We recommend you to call the
.start()
method in theActivity.onCreate()
function.You can call this method more than once as needed.
The SDK begins to execute using the specified configuration and register the provided SIP account.
Observe the registration state changes with the
callbacks.registration(regState -> {})
function. You should also report the push token received from Firebase. Refer the Incoming Calls Over Push section for more information.To terminate the SDK, call
.terminate()
. This unregisters all accounts and shuts down the SDK.The SDK transitions to the Stopped state and then back to Initialized.
To restart the SDK, call the
.start()
method.However, restart should only be done when the SDK reaches the Initialized state.
Foreground Service¶
Acrobits handles the transition from foreground to background, such as when the user leaves the app, to ensure a smooth user experience.
When the app transitions to the background, libSoftphone SDK unregisters from SIP and activates its SIPIS instance. To prevent the Android OS from terminating the process while waiting for backend responses, we register a foreground service to extend the process lifetime for a few seconds after the app moves to the background.
Foreground services are completely managed by libSoftphone SDK. By default, foreground services display a status bar notification to inform the user about ongoing tasks. In addition to the default OS notification that does not provide much information, the Facade SDK enables developers to customize the foreground service notification.
Customizing Foreground Service Notification¶
Use the Facade SDK updateStatusNotification()
to customize the foreground service notification.
Example:
1// Example notification builder
2Notification.Builder builder = new Notification.Builder(context)
3 .setSmallIcon(R.drawable.icon_notification)
4 .setOngoing(true)
5 .setContentTitle("Title!")
6 .setContentText("Content!");
7
8softphone.updateStatusNotification(builder);
Note
You need to pass a Notification.Builder
so that we can change the notification channel.
Integrating with Firebase¶
This section describes how to enable push calls with the integration of Firebase Cloud Messaging (FCM), which allows incoming calls to be received even when the app is asleep or in the background.
Note
Ensure you already set up the VoIP push notifications in both your project and server prior to enabling push notifications. If the setup is not completed yet, go to the Android Push notifications section for detailed instructions.
libSoftphone SDK is fully integrated with the SIPIS push ecosystem. When a softphone app goes to the background, SIPIS takes over the SIP registration on behalf of the app. When SIPIS gets an incoming call INVITE, it sends a high priority push notification to wakes up the app.
To learn more about Acrobits SIPIS, go to doc.acrobits.net/sipis/index.html.
Incoming Calls Over Push¶
SIPIS relies on FCM to deliver incoming call notifications to apps that are asleep or in the background. You are required to integrate FCM into your project. Learn the steps at firebase.google.com/docs/cloud-messaging/android/client.
With FCM integration, you need to ensure the following for the push calls feature to work:
Reporting FCM token to Facade SDK.
Reporting
RemoteMessages
, also known as push payload, to Facade SDK.
The mechanisms of the token and push payload reporting, along with their associated components such as FirebaseViewModel
and PushMessageDelegate
, are discussed in the following sections.
Implementing FirebaseViewModel
¶
The FirebaseViewModel
can hold the FCM token and notify the SDK immediately about the token even if the SDK is initialized later in the app’s runtime.
We recommend developers to implement a view model to manage push-related events.
This view model should expose LiveData
for tokens, remote messages, and push test requests.
An example of the FirebaseViewModel
interface is as follows:
1public interface FirebaseViewModel
2{
3 MutableLiveData<SoftphoneRemoteMessage> getRemoteMessages();
4
5 MutableLiveData<String> getToken();
6
7 MutableLiveData<Duration> getPushTestRequest();
8
9 default void schedulePushTest(Duration delay)
10 {
11 getPushTestRequest().postValue(delay);
12 }
13}
14
15...
16
17firebaseViewModel = new FirebaseViewModelImpl();
Note
The FirebaseViewModel
class name comes from the MVVM architectural pattern, and its implementation does not have to inherit from androidx.lifecycle.ViewModel
.
Getting the PushMessage Delegate¶
The PushMessage delegate is an entity within Facade SDK that processes incoming push tokens and remote messages.
To access the PushMessageDelegate
, access the pushMessage block from the initial configuration builder of the SDK.
Facade SDK has its own RemoteMessage
implementation called SoftphoneRemoteMessage
. SoftphoneRemoteMessage
handles remote messages independently of any specific Firebase package version.
To convert the Firebase RemoteMessage
to the SoftphoneRemoteMessage
, use the following code snippet:
1RemoteMessage remoteMessage;
2
3SoftphoneRemoteMessage softphoneRemoteMessage = SoftphoneRemoteMessage.of(remoteMessage.getData(), remoteMessage.getPriority());
Using the FirebaseViewModel
simplifies the process of integrating push notifications into the initial configuration of the SDK.
The following example attaches the individual callbacks to the FirebaseViewModel
:
1pushMessage -> {
2 firebaseViewModel.getPushToken().observeForever(pushMessage::onNewToken);
3 firebaseViewModel.getPushMessage().observeForever(pushMessage::onMessageReceived);
4 firebaseViewModel.getPushTestRequest().observeForever(pushMessage::schedulePushTest);
5}
Reporting FCM Push Token¶
One of the FirebaseViewModel
benefits is that it can receive and process the push token regardless of whether the token is obtained before or after the SDK initialization.
We recommend you configure the app to check and store the current FirebaseMessaging
token when the app starts up.
To do so, implement the following code:
1void loadToken(FirebaseViewModel model)
2{
3 FirebaseMessaging.getInstance().getToken().addOnCompleteListener(task -> {
4 if (!task.isSuccessful())
5 return;
6
7 var token = task.getResult();
8 if (!TextUtils.isEmpty(token))
9 model.getToken().postValue(token);
10 });
11}
Additionally, to capture token updates from FirebaseMessagingService
and ensure that they are reported to the SDK, implement the following code:
1public static class Acceptor extends FirebaseMessagingService
2{
3
4 ...
5
6 public ViewModel getFirebaseViewModel()
7 {
8 ...
9 }
10
11 @Override
12 public void onNewToken(@NotNull String token)
13 {
14 getFirebaseViewModel().getToken().postValue(token);
15 }
16}
Reporting FCM Remote Messages¶
Ensuring the RemoteMessage
payload to be delivered from your FirebaseMessagingService
to the SDK is very important.
To capture token updates from FirebaseMessagingService
and ensure that they are reported, implement the following code:
1public static class Acceptor extends FirebaseMessagingService
2{
3
4 ...
5
6 public ViewModel getFirebaseViewModel()
7 {
8 ...
9 }
10
11 @Override
12 public void onNewToken(@NotNull String token)
13 {
14 getFirebaseViewModel().getToken().postValue(token);
15 }
16}
Note
Before reporting the newly received push payload, you must ensure that the Facade SDK instance is created prior via the create()
method.
Therefore, if you try to report the push payload to the instance in the CREATED state, it automatically invokes start()
on that instance.
Once the push payload or the RemoteMessage
is delivered to the SDK, the content, particularly the Selector field, is checked if it belongs to one of the stored accounts configured in the SDK.
If it is, the SDK launches a foreground service and attempts to retrieve the call from SIPIS.
Testing the Push Call Implementation¶
Schedule a push test to validate if the communication with SIPIS functions correctly and that the delivery of push notifications to the device.
The following code snippet demonstrates the setup for testing push call implementation:
1final MutableLiveData<Duration> mPushTestRequest = new MutableLiveData<>();
2final Set<Disposable> mDisposables = new HashSet();
3...
4mSoftphone = SoftphoneFacade.create(
5 context,
6 licenseKey,
7 configuration -> configuration
8 .pushMessage(firebase -> {
9 ...
10 firebaseViewModel.getPushTestRequest().observeForever(firebase :: schedulePushTest);
11 })
12 .callbacks(
13 callbacks -> {
14 mDisposables.add(callbacks.pushTest(new PushDelegate()
15 {
16 @Override
17 public void pushTestArrived()
18 {
19 Toast.makeText(getInstance(), "Push test arrived \u2714", Toast.LENGTH_LONG).show();
20 }
21
22 @Override
23 public void pushTestScheduled(PushTestScheduleResult result)
24 {
25 Toast.makeText(getInstance(), "Push test schedule status: " + result.name(), Toast.LENGTH_SHORT).show();
26 }
27 }));
28 }
29 )
30);
31...
32mSoftphone.start();
33...
34mPushTestRequest.postValue(Duration.ZERO);
35....
Push Token Reporter API¶
For deployments that require reporting selector, push token, and app ID to the backend, use to the Push Token Reporter API reference guide at doc.acrobits.net/sipis/index.html. This API is particularly relevant in deployments that do not rely on SIPIS for push call functionality.
Managing SIP Account¶
SIP accounts are specified in the XML format.
To view all the recognized XML nodes and values that can be used to configure SIP accounts, go to the Account XML documentation at doc.acrobits.net/cloudsoftphone/account.html#account-xml.
Creating a SIP Account¶
Set up SIP accounts using the cz.acrobits.ali.Xml
class.
The following code snippets demonstrate different example setups for creating an account:
To include the following code with a basic configuration containing user name, password, and SIP domain in the
Xml
class:1Xml xml = new Xml("account"); 2xml.setAttribute(Account.Attributes.ID, "Testing account"); 3xml.setChildValue(Account.USERNAME, TESTING_URI); 4xml.setChildValue(Account.PASSWORD, TestOnlyUtil.getTestingSipPassword()); 5xml.setChildValue(Account.HOST, "pbx.acrobits.cz");To supply the account configuration via
String
using an XML:1final String acct = 2"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + 3"<account id=\"Testing account\">\n" + 4" <title>My account</title>\n" + 5" <username>1984</username>\n" + 6" <password>misscom</password>\n" + 7" <host>pbx.acrobits.cz</host>\n" + 8" <transport>udp</transport>\n" + 9" <expires>600</expires>\n" + 10" <dtmfOrder>\"rfc2833,audio\"</dtmfOrder>\n" + 11"</account>"; 12Xml account = Xml.parse(acct);To load an account configuration from an
InputStream
, specifically from the app’s assets:1Xml xml = Xml.parse(getAssets().open("account.xml"));
Saving an Account Configuration¶
You can configure to register a SIP account, as well as to set up and save a default account during the SDK initialization. To do so, use the account block to set this up in the initial SDK configuration.
Specify an
Account.Attributes.ID
attribute to give a unique identifier to an account. If this attribute is not specified in Xml, a unique one is generated for that account.To initialize and modify accounts during the runtime of the SDK, use
SoftphoneFacade.saveSingleAccount()
andSoftphoneFacade.saveAccount()
. These two methods differ as follows:
To save or update an account only, call the
SoftphoneFacade.saveSingleAccount()
method. This method ensures that only one SIP account is stored and used by the SDK.To save or update multiple accounts, call the
SoftphoneFacade.saveAccount()
method. Calling this method with different XMLs and IDs results in multiple SIP accounts being registered by the SDK.
Note
If the application uses an account only, use
SoftphoneFacade.saveSingleAccount()
to save or update accounts after the SDK initialization.When you save a new account, the SDK registers the account asynchronously.
Updating Account Configuration¶
You can update an existing account configuration using Facade SDK.
Note
Currently, Facade SDK does not provide an accessor for stored accounts. Developers should use the low-level
Instance.Registration
APIs to access and modify accounts.When you update the configuration of an account, the SDK asynchronously re-registers that account. Meaning, any changes made to the account takes effect without requiring the SDK to be restarted.
The following code snippet illustrates changing the incoming call mode to push for the Testing account:
1AccountXml accountXml = Instance.Registration.getAccount("Testing account").clone();
2accountXml.mergeValue("icm", "push", MergeableNodeAttributes.gui());
3Instance.Registration.saveAccount(accountXml);
To change the configuration of an account using libSoftphone SDK:
Call the
Instance.Registration.getAccount("Testing account").clone()
method to clone the account you want to update.Use appropriate methods or properties of the
AccountXml
object to modify on the account configuration. In this example, the incoming call mode is changed to push by merging the value push into the icm attribute.Call the
Instance.Registration.saveAccount(accountXml)
method to save changes.When
Instance.Registration.saveAccount(accountXml)
is called with theAccount.Attributes.ID
matches the ID of an existing account, this is considered as updating that account configuration.
Deleting an Account¶
Developers can delete accounts by using the account ID in the SoftphoneFacade::removeAccount:
method.
The following code snippet illustrates deleting the Testing account:
1mSoftphone = SoftphoneFacade.create(context, licenseKey, config);
2....
3mSoftphone.removeAccount("Testing account");
Managing Preferences¶
The following section explains how to manage global SDK preferences, also known as preference keys. For managing account level preferences, refer to the Managing SIP Account section.
Preference Key Types¶
Facade SDK provides two types of preferences:
Read only - represented by the
cz.acrobits.libsoftphone.Preferences.ROKey
class.Writable - represented by the
cz.acrobits.libsoftphone.Preferences.Key
class.
You can perform the following actions when the SDK is in the running state:
Read the values of both types of preferences.
Change the value of writable
Preferences.Key
.
The current value of a read-only
Preference.ROKey
cannot be changed.The default values of both
Preferences.Key
andPreference.ROKey
can be overridden using the preferences block in the initial SDK configuration.
Reading Preference Key Values¶
Use the get()
method to retrieve the current value of a preference key.
Note
Call get() after invoking SoftphoneFacade.start()
.
The following code snippet illustrates how to check if SIP traffic logging is enabled:
1SoftphoneFacade instance = SoftphoneFacadeImpl.getInstance();
2boolean enabled = instance.getPreferences().trafficLogging.get();
3android.util.Log.d("Preferences", String.format("Logging is %s", enabled ? "enabled" : "disabled" ));
Changing Preference Key Values¶
Use the set(Type value)
method to change the value of editable preference keys represented by the Key
class.
Note
You are unable to change the value of read-only Preference.ROKey
, but you can override their default values.
Using the example in the former section, the following code snippet illustrates enabling logging by modifying the trafficLogging
preference key:
1SoftphoneFacade instance = SoftphoneFacadeImpl.getInstance();
2boolean enabled = instance.getPreferences().trafficLogging.set(true);
Observing Preference Changes¶
To observe changes to specific Preferences.Key
, implement a PreferencesDelegate
and register it with the Facade’s callbacks.
The following code snippet illustrates observing prefs.volumeBoostPlayback
and handling its change, for example by updating a volume slider position.
1Set<Disposable> disposables = new HashSet();
2mSoftphone = SoftphoneFacade.create(context, licenseKey, config);
3...
4
5PreferencesDelegate delegate = new PreferencesDelegate() {
6 @Override
7 public void onChange(Preferences.Key key)
8 {
9
10 }
11}
12
13CallbacksBuilder callbacks = mSoftphone.getCallbacks();
14disposables.add(callbacks.preferences(
15 prefs -> prefs.volumeBoostPlayback,
16 key ->
17 {
18 // handle the key change
19 // e.g. update volume slider position
20 }
21));
Observing Events from the SDK¶
Developers can register callbacks to observe the desired events from the SDK.
Callback Groups¶
Callbacks are categorized into different groups based on the type or nature of the events they represent. The categorization makes it easier for developers to register and handle specific types of events.
Currently, the available callback groups are as follows:
audio
calls
preferences
pushTest
registration
Using Callbacks¶
When registering callbacks to observe the desired events from the SDK, you can selectively implement a delegate interface for the desired callback group and pass the instance of the delegate to that group.
The following code snippet illustrates an example of implementing CallDelegate
handle call-related events:
1Set<Disposable> disposables = new HashSet();
2mSoftphone = SoftphoneFacade.create(context, licenseKey, config);
3...
4
5CallDelegate delegate = new CallDelegate() {
6 @Override
7 public void callFinished(String remoteUri) {
8 Log.d("CallDelegate", "Call finished");
9 }
10};
11
12disposables.add(mSoftphone.callbacks().calls(delegate));
Callback registration returns a Disposable
object.
The Disposable
object, lightweight and idempotent callable, provides a mechanism to unregister the previously registered callback.
To unregister the callback, use .dispose()
on the returned Disposable
.
Note
The Disposable
implements the same API as the disposables from RxJava. Go to reactivex.io/RxJava/javadoc/io/reactivex/disposables/Disposable.html for more information.
Managing Calls¶
Facade SDK handles calls by using your delegate implementation to manage the assets and information displayed during calls.
Call Assets Delegate¶
When configuring Facade SDK, provide an implementation of CallAssetsDelegate
interface which can resolve assets required for calls, such as ringtones, contact information, and push notification titles.
The CallAssetsDelegate
has a collection of functions that map specific assets with a CallEvent
object.
The following snippet code uses the ExampleCallAssetsDelegate
class as an example implementation of the CallAssetsDelegate
interface:
1configuration.callAssets(new ExampleCallAssetsDelegate())
2
3...
4
5public class ExampleCallAssetsDelegate implements CallAssetsDelegate
6{
7 @Override
8 public AssetFileDescriptor getRingtone(CallEvent callEvent)
9 {
10 // load ringtone for the call
11 }
12
13 @Override
14 public ContactInfo getContactInfo(CallEvent callEvent)
15 {
16 return ContactInfo.of(
17 [ avatar image ],
18 [ display name shown under the avatar ],
19 [ avatar background color for transparent images ]
20 );
21 }
22
23 @Override
24 public String getPushNotificationTitle(CallEvent callEvent)
25 {
26 return getUriFromCallEvent(callEvent);
27 }
28}
Call-Assets-Delegate Methods¶
Implement the following methods when implementing your CallAssetsDelegate
class:
getRingtone()
- provide a ringtone that plays for an incoming call.
getContactInfo()
- provide information about the contact that displays on the incoming call screen and on the user interface during a call.
getPushNotificationTitle()
- change the text displayed in the push notification title for the call.
Outgoing Calls¶
Once Facade SDK is initialized and the configured account is registered, placing an outgoing call is simple.
As shown in the following snippet code, use the placeCall
method on the SoftphoneFacade
and pass the SIP address of the remote party as a parameter.
1private SoftphoneFacade mSoftphone;
2
3...
4
5mSoftphone.placeCall("remote@sip.account");
When a call is placed, the SDK invokes your CallAssetsDelegate
implementation to load information about the remote party. The active call screen is displayed automatically.
Incoming Calls¶
The SDK automatically handles incoming calls. The incoming call screen displays when the SDK receives a SIP INVITE or an incoming call Firebase notification.
The SDK again uses your CallAssetsDelegate
implementation to load information about the remote party on the incoming call screen.
Enabling Logging¶
Enable logging to capture important events and activities that occur within the SDK. By enabling the logger with Facade SDK, developers can determine whether to control the logging behavior at specific moments during runtime, or to start logging whenever the application starts operating.
The following snippet code illustrates the methods contained in the Logger
interface:
1public interface Logger
2{
3 CharSequence getLogs();
4 void startLogging();
5 void stopLogging();
6 boolean isLogging();
7}
By default, the logger is disabled. There are two ways to enable the logger:
To enable the logger during runtime, call
facade.getLogger()
to access the logging controller. The controller allows you to control the logger and get current logs.To enable the logger and start logging whenever the application runs, include the
trafficLogging
preference key in the configuration block. Setting thetrafficLogging
totrue
enables logging from the start, as shown in the following code snippet:1configuration 2 .preferences(preferences -> preferences 3 .overrideDefault(prefs -> prefs.trafficLogging, true) 4 )
The logger is by default disabled, which means no logs are printed to LogCat, and the getLogs()
function returns null
.
Once the logger is enabled, all logs are printed to LogCat, and you can access them with getLogs()
.
Accessing Telemetry¶
You can access telemetry information through Facade SDK and register to receive specific or all telemetry events.
To register for individual telemetry events, use the
.on(Class, Consumer)
function. The events all inherit from a commonTelemetryEvent
interface.To listen for all events, use the
.onAny(Consumer)
function.
The following snippet code demonstrates examples of using these functions to log events:
1TelemetryProvider telemetry = mSoftphone.getTelemetry();
2
3telemetry.on(InAppCallErrorCaused.class, event -> android.util.Log.i("EVENT-ERR", event.getErrorMessage()));
4
5telemetry.onAny(anyEvent -> android.util.Log.i("EVENT", event));
All the events also implement the .toString()
method to convert an event object to its string representation.