Create a Custom Recent Calls Service

Last edit: 2023.07.27

The IVI platform comes with a RecentCallsService interface for accessing recent calls information. A product may provide its own implementation of the RecentCallsService interface or use an existing implementation. When the existing implementation of a RecentCallsService is inadequate (for example if we want to only show the recent calls of the day, filtering out older calls) it is possible to define a custom recent calls service. In order for the UI to be able to display recent calls from this service, a custom recent calls service needs to be written. This document describes how to do this.

How to create a custom recent calls service

The following sections describe how to create a custom recent calls service implementation.

Example code illustrating how to implement the concepts described in this document can be found in examples/telephony/customrecentcalls.

Service module setup

To create a custom recent calls service, add a manifest file to your module and add a dependency to the RecentCallsService to your Gradle file.

Your AndroidManifest.xml should contain:

<?xml version="1.0" encoding="utf-8"?>
<manifest package="com.example.ivi.example.telephony.customrecentcalls" />

Your build.gradle.kts file should contain:

1dependencies {
2 implementation(libraries.iviPlatformRecentcallsApiServiceRecentcalls)

Service configuration

To configure a recent calls service to use your custom implementation, define a service host configuration class that inherits from the IviServiceHostConfig class. This class should be placed in the application Gradle build file.


1val customRecentCallsServiceHost by extra {
2 IviServiceHostConfig(
3 serviceHostBuilderName = "CustomRecentCallsServiceHostBuilder",
4 implementationModule = ExampleModuleReference("examples_telephony_customrecentcalls"),
5 interfaces = listOf(
6 IviServiceInterfaceConfig(
7 serviceName = "RecentCallsService",
8 serviceApiModule = IviPlatformModuleReference("platform_recentcalls_api_service_recentcalls")
9 )
10 )
11 )

In this configuration, the services_customrecentcalls module defines the implementation for the platform_recentcalls_api_service_recentcalls interface.

In order to create the service host configuration named CustomRecentCallsServiceHost, the IVI platform needs a service host builder class with the specific name CustomRecentCallsServiceHostBuilder.


1class CustomRecentCallsServiceHostBuilder : IviServiceHostBuilder() {
3 override fun build(iviServiceHostContext: IviServiceHostContext) =
4 SimpleIviServiceHost(
5 iviServiceHostContext,
6 setOf(CustomRecentCallsService(iviServiceHostContext))
7 )
9 companion object

Note: Every service host configuration needs to be registered in your application. This is so that the platform knows which service should be started with which implementation when a client requires the access to a service api.

To register this configuration, add the service host to your application Gradle file:


1ivi {
2 optInToExperimentalApis = true
4 application {
5 enabled = true
6 services {
7 // Replace the default recent calls service host with the custom recent calls service
8 // host.
9 removeHost(recentCallsServiceHost)
10 addHost(customRecentCallsServiceHost)
11 }
12 }

Service definition

In order to create a recent calls service implementation you need to create a class that inherits from the RecentCallsServiceBase base class.


1internal class CustomRecentCallsService(iviServiceHostContext: IviServiceHostContext) :
2 RecentCallsServiceBase(iviServiceHostContext) {

Note: The recent calls service implementation can define any kind of source as the list of recent calls, for example the Android CallLog provider.

In this example, the recent calls service always returns a list of two hard-coded calls. The list of recent calls contains those two recent calls after initialization. The list recentCallsSource is the source of recent calls:


1// The source of recent calls.
2private val recentCallsSource = listOf(
3 RecentCallsService.RecentCall(
4 type = RecentCallsService.CallType.INCOMING,
5 displayName = "Caller",
6 phoneNumber = PhoneNumber("+2811111111", PhoneNumberType.Mobile),
7 duration = Duration.ofSeconds(60),
8 creationTime =
9 ),
10 RecentCallsService.RecentCall(
11 type = RecentCallsService.CallType.OUTGOING,
12 displayName = "Receiver",
13 phoneNumber = PhoneNumber("+2822222222", PhoneNumberType.Work),
14 duration = Duration.ZERO,
15 creationTime = Instant.parse("2020-04-09T10:15:30.00Z")
16 ),

Service lifecycle

To manage the initialization and destruction of the service, override the onCreate and onDestroy methods.

When the service is created:


1override fun onCreate() {
2 super.onCreate()
3 // Initialize the synchronization status.
4 phoneBookSynchronizationStatus = PhoneBookSynchronizationStatus.NO_CONNECTED_DEVICES
5 // Initialize the recentCallsDescending property with an empty list.
6 recentCallsDescending = emptyList()
7 // Set the service ready and clients can call any Api of the service.
8 serviceReady = true
9 // The source of recent calls is ready and synchronization starts.
10 phoneBookSynchronizationStatus = PhoneBookSynchronizationStatus.SYNCHRONIZATION_IN_PROGRESS
11 // Update recentCallsDescending with the list of recent calls from the source.
12 // Make sure that the list is in descending chronological order.
13 // If a client (typically a view model) requires the list in a different order,
14 // then it should resort the list before use.
15 recentCallsDescending = recentCallsSource.sortedByDescending(RecentCall::creationTime)

then the RecentCallsService properties recentCallsDescending and phoneBookSynchronizationStatus have been initialized.

When the service is destroyed:


1override fun onDestroy() {
2 // Put here cleaning code if necessary.
3 super.onDestroy()