Android SDK Migration document from 2.x to 3.x
This document details the necessary changes required when migrating from Android SDK version 2.x to version 3.x.
The Webex Connect Android SDK version 3.0.0 is a major rewrite of version 2.x. This SDK is structured into modular components, each designed to offer specific functionality. Version 3.0.0 of the SDK is built in Kotlin using Android SDK Tools 35 and requires Android API level 21 or later.
Note
The current version of the modular SDK does not migrate registration data, hence we recommend continuing to use the existing 2.x version. Data migration will be added in a future version, helping to ensure a smooth transition to the modular SDK.
Please refer to the table below for more details about each module and its functionality. This information will help you understand what's available in each module and decide which modules you want to integrate into your application.
Module | Description |
---|---|
webexconnect-core | The core module is the foundation of the Webex Connect SDK. It provides essential functionality that all other modules depend on, including initialization, configuration, registration, and shared utilities. |
webexconnect-push | The push module enables your application to receive and handle push notifications. It abstracts the underlying push notification service, providing customized support for notification management. |
webexconnect-fcm | The fcm module integrates Firebase Cloud Messaging to handle push notifications for devices with Google Play Services. |
webexconnect-hms | The hms module integrates Huawei Mobile Services to handle push notifications for devices with Huawei Mobile Services. |
webexconnect-inappmessaging | The inappmessaging module offers both one-way and two-way messaging capabilities for your app. |
Prerequisites
Component | Requirement |
---|---|
Android Operating System | Android OS 5.0 (API 21) and higher. |
Software | Latest version of Android Studio Webex Connect Android SDK |
Accounts | - A valid Google account (required only if you're using FCM push services) - A valid HMS account (required only if you're using HMS push services) - An active Webex Connect account. |
Integration
The following sections outline the most common tasks required to integrate the Webex Connect SDK into your Android application. While many methods remain similar to the previous version of the SDK, many of the classes and interfaces have changed, please refer the mapping tables at the end of this guide for more details.
Dependencies
The v2.x dependencies must be removed from your gradle files and replaced with the required v3.x dependencies. You only need to include dependencies that correspond to the features you wish to use.
Remove v2.x gradle dependencies:
Your gradle file will contain one of the dependencies listed below.
//For FCM builds
dependencies {
implementation 'com.webex.connect:core-gms-full:2.x.x'//Full fat SDK
implementation 'com.webex.connect:core-gms-lite:2.x.x'//Lite SDK
} // Use the appropriate version
//For HMS builds
dependencies {
Implementation 'com.webex.connect:core-hms-lite:2.x.x' //Full fat SDK
Implementation 'com.webex.connect:core-hms-full:2.x.x' //Lite SDK
}// Use the appropriate version
Add v3.x gradle dependencies:
Add the dependencies that correspond to the features you plan to use.
dependencies {
//FCM Module - Required to use Firebase Cloud Messaging as the push provider.
implementation 'com.webex.connect:webexconnect-fcm:3.0.0'
//HMS Module - Required to use Huawei Mobile Services as the push provider.
implementation 'com.webex.connect:webexconnect-hms:3.0.0'
//In-App Messaging - Required to use In-App messaging capabilities within your app.
implementation 'com.webex.connect:webexconnect-inappmessaging:3.0.0'
}//It is recommended to use the latest version of each module.
dependencies {
//FCM Module - Required to use Firebase Cloud Messaging as the push provider.
implementation("com.webex.connect:webexconnect-fcm:3.0.0")
//HMS Module - Required to use Huawei Mobile Services as the push provider.
implementation("com.webex.connect:webexconnect-hms:3.0.0")
//In-App Messaging - Required to use In-App messaging capabilities within your app.
implementation("com.webex.connect:webexconnect-inappmessaging:3.0.0")
} //It is recommended to use the latest version of each module.
Important
You should not include both FCM and HMS modules within the same build variant.
Note
For information on integrating dependencies manually, please refer to our Quick Start guide.
Android manifest configuration
This section details the changes required to the AndroidManifest.xml file. Before removing any of the listed permissions, please ensure your app does not use these for functionality unrelated to the SDK.
Remove v2.x entries.
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<application
android:name="YOUR_APPLICATION_CLASS_NAME"
android:allowBackup="true"
android:label="@string/app_name"
android:theme="@style/AppTheme">
<activity
android:name="YOUR_ACTIVITY_NAME"
android:label="@string/app_name">
<intent-filter>
<!-- OPTIONAL enables support for push deeplinks -->
<data
android:host="command"
android:scheme="@string/app_id"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<receiver
android:name="com.imimobile.connect.core.messaging.ICMessagingReceiver"
android:enabled="true"
android:exported="false"
android:permission="com.imimobile.connect.core.permission.PUSH_PERMISSION">
<intent-filter>
<action android:name="com.imimobile.connect.core.rtmevent"/>
<action android:name="com.imimobile.connect.core.notification.click"/>
<action android:name="com.imimobile.connect.core.intent.notification.RECEIVE"/>
</intent-filter>
</receiver>
</application>
Add v3.x entries.
<!-- PERMISSIONS -->
<!-- REQUIRED for connecting to Webex Connect -->
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<!-- Replace YOUR_APPLICATION_CLASS_NAME with the name of the class specific to your app.-->
<application
android:name="YOUR_APPLICATION_CLASS_NAME"
android:allowBackup="true"
android:label="@string/app_name"
android:theme="@style/AppTheme">
<activity
android:name="YOUR_ACTIVITY_NAME"
android:label="@string/app_name">
<intent-filter>
<!-- OPTIONAL Enables support for push deeplinks -->
<data
android:host="command"
android:scheme="@string/app_id"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
Configure ProGuard Rules
Several ProGuard rules have changed within v3.x, the old v2.x rules must be removed and replaced with the new v3.x rules.
Remove v2.x ProGuard entries:
-dontwarn org.eclipse.jetty.**
-dontwarn com.google.firebase.messaging.FirebaseMessaging
-dontwarn javax.servlet.**
-dontwarn org.slf4j.**
# for sqlcipher
-keep class net.sqlcipher.** { *; }
-keep class net.sqlcipher.database.* { *; }
# WorkManager
-keep class * extends androidx.work.Worker
-keep class * extends androidx.work.InputMerger
-keep public class * extends androidx.work.ListenableWorker {
public <init>(...);
}
-keep class androidx.work.WorkerParameters
# For MQTT
-keep class org.eclipse.paho.client.mqttv3.** {*;}
-keep class org.eclipse.paho.android.service.** { *; }
-keepclasseswithmembers class org.eclipse.paho.** {*;}
#Proguard rules for HMS - Please include the following rules only if you integrate the HMS SDK.
-ignorewarnings -keepattributes *Annotation*
-keepattributes Exceptions
-keepattributes InnerClasses
-keepattributes Signature
-keepattributes SourceFile,LineNumberTable
-keep class com.hianalytics.android.**{*;}
-keep class com.huawei.updatesdk.**{*;}
-keep class com.huawei.hms.**{*;}
Add v3.x ProGuard entries:
-keep,includedescriptorclasses class com.webex.connect.** { *; }
-keep,includedescriptorclasses interface com.webex.connect.** { *; }
# sqlcipher
-keep,includedescriptorclasses class net.zetetic.database.** { *; }
-keep,includedescriptorclasses interface net.zetetic.database.** { *; }
# MQTT - Please include the following rules only if you integrate the In-App Messaging module.
-keep class org.eclipse.paho.client.mqttv3.** {*;}
-keep class org.eclipse.paho.android.service.** { *; }
-keepclasseswithmembers class org.eclipse.paho.** {*;}
#(Optional)- Please include the following rules only if you integrate the HMS module.
-ignorewarnings
-keepattributes *Annotation*
-keepattributes Exceptions
-keepattributes InnerClasses
-keepattributes Signature
-keepattributes SourceFile,LineNumberTable
-keep class com.huawei.hianalytics.**{*;}
-keep class com.huawei.updatesdk.**{*;}
-keep class com.huawei.hms.**{*;}
Package imports
The v3.x SDK uses new package names, remove all com.imimobile.connect.* package imports and replace with the new com.webex.connect.* equivalents. It is recommended to use your IDEs inbuilt feature to include the relevant imports as you update your code, however, you may also refer to the tables below.
SDK startup
The v3.x SDK uses Android App Startup to automatically register included modules and start the SDK. Therefore, you should remove any existing v2.x startup code. Locate your call to IMIconnect.startup and remove the code; this is usually found within the onCreate method of your Application class.
Remove the v2.x startup code:
public class MyApplication extends Application
{
@Override
public void onCreate()
{
super.onCreate();
try
{
IMIconnect.startup(this);
} catch (ICException e)
{
e.printStackTrace();
}
}
}
Note
If you have disabled App Startup for your application, please follow the manual startup instructions provided within our Quick Start guide: Manual Startup Instructions.
Device registration
The process for device registration is the same on v3.x as it is on v2.x, but class names have changed.
Remove v2.x registration code:
var userId = "YOU_USER_ID";
var deviceProfile = new ICDeviceProfile(ICDeviceProfile.getDefaultDeviceId(), userId);
IMIconnect.register(deviceProfile, new ICRegistrationCallback()
{
@Override
public void onRegistrationComplete(final Bundle bundle, final ICException exception)
{
if (exception != null)
{
Log.e("Registration", "Registration failed! Reason:" + exception.toString());
}
else
{
Log.d("Registration", "Registration succeeded!");
}
}
});
Replace with v3.x code:
val webexConnect: WebexConnect = WebexConnect.instance
// Initialize a device profile
val userId = "YOUR_USER_ID"
val deviceProfile = DeviceProfile(DeviceProfile.defaultDeviceId, userId)
// Register the device
webexConnect.register(deviceProfile) { jsonObject: JSONObject?, exception: WebexConnectException? ->
if (exception != null) {
Log.e("Registration", "Registration failed!", exception)
} else {
Log.d("Registration", "Registration succeeded!")
}
}
WebexConnect webexConnect = WebexConnect.getInstance();
// Initialize a device profile
val userId = "YOUR_USER_ID";
val deviceProfile = new DeviceProfile(DeviceProfile.getDefaultDeviceId(), userId);
// Register the device
webexConnect.register(deviceProfile, (jsonObject, exception) -> {
if (exception != null) {
Log.e("Registration", "Registration failed!", exception);
} else {
Log.d("Registration", "Registration succeeded!");
}
return Unit.INSTANCE;
});
Push Notifications
Default notification channel id:
The default channel id constant has been moved to the NotificationFactory interface and the ICConstants class has been removed.
Remove v2.x code:
ICConstants.DEFAULT_CHANNEL_ID
Replace with v3.x code:
NotificationFactory.DEFAULT_CHANNEL_ID
Push Messaging Listeners
The v2.x SDK emitted incoming push through the ICMessagingReceiver
class and the ICMessageListener
interface, as ICMessage objects. The v3.x SDK emits push as PushMessage objects through the PushMessagingListener
interface. Listeners are registered via the PushMessaging
interface.
Remove v2.x code
//Push via receiver
public class MyReceiver extends ICMessagingReceiver
{
@Override
protected void onMessageReceived(final Context context, final ICMessage message)
{
//Handle push
}
}
//Push via listener
ICMessaging.getInstance().registerListener(new ICMessagingListener()
{
@Override
public void onMessageReceived(ICMessage icMessage)
{
//Handle push
}
}
Replace with v3 code:
PushMessaging.instance.registerMessagingListener { pushMessage: PushMessage ->
//Handle push
}
var pushMessaging = PushMessaging.getInstance();
pushMessaging.registerMessagingListener(pushMessage -> {
//Handle push
return Unit.INSTANCE;
});
Notification Customization
Customization of push notifications was handled in v2.x by inheriting from ICNotificationFactory and overriding the ICNotificationReceiver.getNotificationFactory method. In v3.x there are two ways to customize the notification build process.
If you currently inherit from ICNotificationFactory, please replace the code with one of the following approaches.
To add customization on top of the SDK notification build process, implement the NotificationBuilderCallback interface and set the callback on the default NotificationFactory:
class MyNotificationBuilder: NotificationBuilderCallback
{
override fun getActionIconId(
context: Context,
message: PushMessage,
action: String,
identifier: String
): Int
{
//Return id of the icon specific to the action
return 0
}
override fun onBuildNotification(
context: Context,
message: PushMessage,
notificationId: Int,
builder: NotificationCompat.Builder
)
{
//Customize notification build process here
}
}
public class MyNotificationBuilder implements NotificationBuilderCallback {
@Override
public int getActionIconId(Context context, PushMessage message, String action, String identifier) {
// Return id of the icon specific to the action
return 0;
}
@Override
public void onBuildNotification(Context context, PushMessage message, int notificationId, NotificationCompat.Builder builder) {
// Customize notification build process here
}
}
//PushMessaging contains a deault implementation of NotificationFactory
//Use it to set your notification builder callback
PushMessaging.instance.notificationFactory?.notificationBuilderCallback = MyNotificationBuilder()
Alternatively, to entirely replace the inbuilt notification build process, implement the NotificationFactory interface and set PushMessaging.instance.notificationFactory
to your custom implementation:
//Sample assumes the same channelId is used for each notification
//You may wish to dynamically assign a channelId based on the push data
class MyNotificationFactory(private val channelId: String): NotificationFactory
{
//Callback can be null as you will handle the build within createNotification
override var notificationBuilderCallback: NotificationBuilderCallback? = null
override fun createNotification(
context: Context,
message: PushMessage,
notificationId: Int,
smallIconResourceId: Int,
largeIcon: Bitmap?,
bigPicture: Bitmap?
): Notification
{
var builder = Notification.Builder(context, channelId)
//Build Notification object
return builder.build();
}
}
PushMessaging.instance.notificationFactory = MyNotificationFactory()
InApp Messaging
Message Store
The ICDefaultMessageStore found in v2.x has been renamed to DefaultMessageStore in v3.x, and is set using the InAppMessaging.messageStore property.
Remove v2.x code:
var store = ICDefaultMessageStore(context, password)
ICMessaging.setMessageStore(store)
Replace with v3.x code:
var store = DefaultMessageStore.create(context, "your password")
InAppMessaging.instance.messageStore = store
DefaultMessageStore store = DefaultMessageStore.create(context, "your password");
InAppMessaging.getInstance().setMessageStore(store);
Intercepting incoming messages
The v2.x SDK emitted incoming messages and connection status changes through the ICMessagingReceiver
class and the ICMessageListener
. The v3.x SDK uses InAppMessagingListener
and ConnectionStatusListener
. Listeners are registered via the InAppMessaging
interface.
Remove v2.x code:
Remove any code that uses ICMessagingReceiver
and ICMessageListener
for handling incoming messages and connection status changes.
//In App via receiver
public class MyReceiver extends ICMessagingReceiver
{
@Override
protected void onMessageReceived(final Context context, final ICMessage message)
{
//Handle incoming message
}
protected void onConnectionStatusChanged(Context context, ICConnectionStatus status, ICException exception)
{
//Handle connection status change
}
}
//In App via listener
ICMessaging.getInstance().registerListener(new ICMessagingListener()
{
@Override
public void onMessageReceived(ICMessage icMessage)
{
//Handle incoming message
}
public void onConnectionStatusChanged(ICConnectionStatus status, ICException exception)
{
//Handle connection status change
}
}
Replace with v3.x code:
val inAppMessaging = InAppMessaging.instance
inAppMessaging.registerMessagingListener { inAppMessage ->
//Handle incoming message
}
inAppMessaging.registerConnectionStatusListener { connectionStatus ->
//Handle connection status change
}
InAppMessaging.getInstance().registerMessagingListener(inAppMessage -> {
//Handle incoming message
return Unit.INSTANCE;
});
InAppMessaging.getInstance().registerConnectionStatusListener(connectionStatus ->
{
//Handle connection status change
return Unit.INSTANCE;
});
Class Name Changes, Method Name Changes, and New Properties
The following tables detail the class and interface mappings between v2.x and v3.x, please refer to these tables to help transition the rest of your codebase.
Note that in v3.x, we have replaced the majority of callback interfaces with typealias for improved code readability and simplicity. Please refer to the method-specific documentation relevant to your application to understand the changes and update your implementation accordingly.
Core Module
Class Name mapping from 2.x to 3.x
Push Module
Push-FCM Module :
Push-HMS Module :
In-App Messaging Module :
By following the steps outlined in this document and updating your code to reflect the changes in class names, method names, and new properties, you should be able to successfully migrate from the monolithic v2.x SDK to the modular v3.x SDK. Please ensure that you thoroughly test your application after making these changes to confirm that all functionalities are working as expected.
Updated about 1 month ago