Webex Teams

SDK for Android

Integrate Webex Teams into your Android apps

Features

Integrate the Android SDK into your Android apps to place and receive Webex Teams video calls:

  • Audio and/or video 1:1 calling
  • Group space calling new
  • Dial by email, Webex Teams User ID, or SIP address
  • Call and event controls, including DTMF
  • Audio and video call control
  • View shared content new
  • View content and video simultaneously new
  • Maximum bandwidth controls new
  • Create Teams, Spaces, Memberships, and Messages
Getting Started Guide

If you are working with Android, Webex Teams allows you to integrate secure and convenient Webex Teams messaging and calling features in your Android apps.

The Webex Teams Android SDK gives you the ability to customize your app and to seamlessly access powerful Webex Teams collaboration features without ever having to leave your mobile app. Use the Android SDK to apply your own UI for customization and still use client-side API calls to embed Webex Teams voice and video calling directly into your application. With the Webex Teams Android SDK, you can also connect end users from your app to any Webex Teams app/device and SIP device.

Overview

  • Create Webex Teams Rooms
  • Post Webex Teams Messages
  • Make and receive audio/video calls

Requirements

  • Android Studio 2.3 or later
  • Android SDK Tools 25 or later
  • Android API Level 21 or later
  • Java JDK 8
  • Gradle for dependency management
  • Webex Teams Account
  • Use of this SDK requires the spark:all scope

Step 1: Integrate the Webex Teams Android SDK

First, you need to add the following repository to your top-level build.gradle file of your project module in Android Studio.

To do this, open the Project Structure view and then open your build.gradle (Project: YourApplication Name) file. Then, add mavenCentral() underneath the allprojects -> repositories code blocks, as shown below:

allprojects {
    repositories {
        jcenter()
        maven {
            url 'https://devhub.cisco.com/artifactory/sparksdk/'
        }
    }
}

Step 2: Add the Webex Teams Android SDK Library

Now you need to include the Webex Teams Android SDK library module as a dependency for your app.

To do this, add the following code and configuration to the dependencies block of the build.gradle (Module: app) file, as shown below:

dependencies {
    compile('com.ciscospark:androidsdk:1.3.0@aar', {
        transitive = true
    })
}

Step 3: Enable Multidex Support and Update Packaging Options

In order for your app code to compile correctly after integration, you will need to enable multidex support for your app.

To do this, add multiDexEnabled true to the build.gradle (Module: app) file, under defaultConfig, as shown below:

android {
    defaultConfig {
        multiDexEnabled true
    }
}

Note: Enabling multidex support allows your app build process to generate more than one (DEX) file when you compile your app. See the description of multidex in the Android documentation for more information.

You will also need to exclude the rxjava.properties file. To do this, add these packagingOptions to the build.gradle (Module: app) file, as shown below:

packagingOptions {
    exclude 'META-INF/rxjava.properties'
}

Now, just sync the gradle dependencies to ensure that everything integrates properly.

Keep reading for details about how to use the Webex Teams Android SDK with your application, starting with authenticating the user, and then moving on to creating rooms and sending messages.

App Integration and Authentication

Before your app can use Webex Teams on behalf of another user, you will need to register a Webex Teams Integration. Your app will either need to authenticate users via an OAuth grant flow for existing Webex Teams users, or via a JSON Web Token for guest users that do not have a Webex Teams account.

Once registration is complete, you will get a Client ID and Client Secret for use with the app. These can be used to generate a token with the proper scopes.

See the examples below for creating new Spark instances for existing Webex Teams users or for guest users who do not have a Webex Teams account.

Example #1 - Create a new Spark instance using Webex Teams authentication (OAuth-based):

String clientId = "YOUR_CLIENT_ID";
String clientSecret = "YOUR_CLIENT_SECRET";
String scope = "spark:all";
String redirectUri = "Sparkdemoapp://response";

OAuthWebViewAuthenticator authenticator = new OAuthWebViewAuthenticator(clientId, clientSecret, scope, redirectUri);
Spark spark = new Spark(activity.getApplication(), authenticator)
if (!authenticator.isAuthorized()) {
    authenticator.authorize(webView, new CompletionHandler<Void>() {
        @Override
        public void onComplete(Result<Void> result) {
            if (!result.isSuccessful()) {
                System.out.println("User not authorized");
            }
        }
    });
}

Example #2 - Create a new Spark instance using Guest Issuer authentication (JWT-based):

JWTAuthenticator authenticator = new JWTAuthenticator();
Spark spark = new Spark(activity.getApplication(), authenticator);
if (!authenticator.isAuthorized()) {
    authenticator.authorize(myJwt);
}

Using Webex Teams with your App

Now that you're authenticated, you can use Webex Teams. You can create a room, add users, and post messages using the SDK.

Create a room:

spark.rooms().create("Hello World", null, new CompletionHandler<Room>() {
    @Override
    public void onComplete(Result<Room> result) {
        if (result.isSuccessful()) {
            Room room = result.getData();
            String roomId = room.getId();
        }
        else {
            SparkError error = result.getError();
        }
    }
});

Add users to the room:

spark.memberships().create(roomId, null, "person@example.com", true, new CompletionHandler<Membership>() {
    @Override
    public void onComplete(Result<Membership> result) {
        if (result.isSuccessful()) {
            Membership membership = result.getData();
        }
        else {
            SparkError error = result.getError();
        }
    }
});

Post messages to the room:

spark.messages().post(roomId, null, null, "Hello there", null, null, new CompletionHandler<Message>() {
    @Override
    public void onComplete(Result<Message> result) {
        if (result.isSuccessful()) {
            Message message = result.getData();
        }
        else {
            SparkError error = result.getError();
        }
    }
});

Webex Teams Audio/Video Calling

This is the most significant SDK feature which enables users to make and receive audio/video calls via Webex Teams. Calling in the SDK is very easy to use.

First, you need to register the device in order to send and receive calls:

spark.phone().register(new CompletionHandler<Void>() {
    @Override
    public void onComplete(Result<Void> result) {
        if (result.isSuccessful()) {
            // Device registered
        }
        else {
            // Device not registered, and calls will not be sent or received
        }
    }
});

Once registration is complete, you can make an outgoing call, as shown below:

spark.phone().dial("person@example.com", MediaOption.audioVideo(local, remote), new CompletionHandler<Call>() {
    @Override
    public void onComplete(Result<Call> result) {
        Call call = result.getData();
        if (call != null) {
            call.setObserver(new CallObserver() {
                @Override
                public void onRinging(Call call) {

                }

                @Override
                public void onConnected(Call call) {

                }

                @Override
                public void onDisconnected(CallDisconnectedEvent
                callDisconnectedEvent) {

                }

                @Override
                public void onMediaChanged(MediaChangedEvent
                mediaChangedEvent) {

                }
            });
        }
        else {
            SparkError error = result.getError();
        }
    }
});

These calls can be made to Webex Teams users/devices, Telepresence systems, SIP devices, and regular telephones. If the user calls a telephone system such as an IVR, the SDK also supports DTMF transport so users can navigate IVR menus.

To send DTMF, simply invoke call.send(dtmf, completionHandler):

// Send DTMF
Call.sendDTMF(dtmfEvent, new CompletionHandler<Void>() {
    @Override
    public void onComplete(Result<Void> result){

    }
});

To receive a call:

spark.phone().setIncomingCallListener(new Phone.IncomingCallListener() {
    @Override
    public void onIncomingCall(Call call) {
        call.answer(MediaOption.audioVideo(local, remote), new CompletionHandler<Void>() {
            @Override
            public void onComplete(Result<Void> result) {
                if (result.isSuccessful()) {
                    // success
                }
                else {
                    SparkError error = result.getError();
                }
            }
        });
    }
});

Complete Demo App

A complete demo application is available to see the complete functionality of the SDK.

Incoming Call Notification Guide

The Webex Teams Android SDK enables you to embed the Webex Teams calling and meeting experience into your Android mobile application. This SDK provides APIs to make and receive audio/video calls.

In order to receive audio/video calls, the user needs to be notified when someone is calling them. The Webhook/Push Notification Server example below demonstrates how you can write a server application to receive incoming call notifications from Webex Teams and then use Google Firebase Cloud Messaging (FCM) to notify the mobile application when a call is incoming.

For more information about Google push notifications, please see the Firebase documentation.

Note

The webhook resource described in this guide is currently in beta. It is limited to 1:1 calls and may change in the future. If you're interested in using this webhook for your Android app, please contact the Webex Developer Support team to add your account to the beta program.

Receiving Incoming Call Notifications

The diagram and step-by-step procedures that follow show the workflow of the webhooks, along with the push notifications that would occur, if the example Webhook/Push Notification server was deployed to the public Internet.

  1. In this example, the user launches the Firebase Cloud Messaging (FCM) client application on their Android mobile device. This automatically registers the client application to the Google FCM.
  2. Next, the user obtains the device token from FCM by using the onTokenRefresh() callback function. For more information on this step, see Accessing the Device Token From the Android App below.
  3. Now, the user must register the device token that is returned by the FCM, along with the current user's user ID, to the Webhook/Push Notification Server as shown below. The server will store this information locally in a database.
    let paramaters: Parameters = [
        "email": email,
        "voipToken": voipToken,
        "msgToken": msgToken,
        "personId": personId
    ]
    Alamofire.request("https://example.com/register", method: .post, parameters: paramaters, encoding: JSONEncoding.default).validate().response { res in
        // ...
    }
  4. After the user logs into Webex Teams,they can use the Webhook API to create a webhook in the Webex Teams cloud. The target URL of the webhook must be the /webhook REST endpoint of this server. Note that this URL must also be publicly accessible from the Internet.
    spark.webhooks().create("Incoming Call Webhook", targetUrl, "callMemberships", "created", "status=notified&personId=me", null, new CompletionHandler<Webhook>() {
        @Override
        public void onComplete(Result<Webhook> result) {
            if (result.isSuccessful()) {
                Webhook webHook = result.getData();
                // ...
            } else {
                // ...
            }
        }
    });
    
  5. The remote party will then make a call using Webex Teams.
  6. Webex Teams receives the call and will trigger the webhook. The incoming call event is sent to the target URL which will be the /webhook REST endpoint of this Webhook/Push Notification server.
  7. The Webhook/Push Notification Server will then look up the device token from the database by the user ID in the incoming call event. The server will then send the notification, along with the device token and incoming call information, to the FCM.
  8. The FCM then pushes a notification to the Android device.
  9. Your Android application receives the push notification and uses the SDK API to accept the call from the Webex Teams Cloud.

For more information about Steps 1, 2, 7 and 9, please see the following sections of this document.

For more information about Steps 4 and 6, please see Webex Teams Webhooks Explained.

Accessing the Device Token From the Android App

  1. To access the device token from the Android App, you must first set up an FCM Client App on Android. This functionality is demonstrated in this quick sample, which is already setup with Firebase dependencies.
  2. Add Firebase to your Android project with Firebase Console. Please note that the package name that you are required to fill in should be the same as the Android app that was previously created.
  3. Next, download the google-services.json file from the newly created project and copy it to the Android client’s app/ folder. Then, sync this file with the Gradle files from within Android Studio.
  4. Now you need to build and run the app from Android Studio. When the app is launched, the Android client's device token can be captured using the onTokenRefresh() callback function.

How to Send Messages to Client App

Note that there are two types of messages in FCM (Firebase Cloud Messaging). Both are shown below:

  1. Display Messages: These types of messages trigger the onMessageReceived() callback only when your app is in foreground
  2. Data Messages: Theses messages trigger the onMessageReceived() callback even if your app is in foreground/background/killed

You can send a display message using the Firebase Console. However, at this time, the Firebase team has not developed a UI to send data-messages yet. This means that the app needs to be running or you will not receive notification from the Firebase Console.

To send a data message to the client, you have to create a POST to the following URL, as shown below:

POST https://fcm.googleapis.com/fcm/send

You also need to use the following headers in your post:

  • Key: Content-Type, Value: application/json
  • Key: Authorization, Value: key=<your-server-key>

The data message must also contain topics in the body of the message, as shown below:

{
    "to": "/topics/my_topic",
    "data": {
        "my_custom_key" : "my_custom_value",
        "my_custom_key2" : "my_custom_value2"
    }
}

If you want to send the message to specific devices, the following data must also be included in the body:

{
    "data": {
        "my_custom_key" : "my_custom_value",
        "my_custom_key2" : "my_custom_value2"
    },
    "registration_ids": ["{device-token}","{device2-token}","{device3-token}"]
}

Note

To get your server key, you can find it in the Firebase Console at: “Your project name” > Settings > Project settings > Cloud messaging > Server Key

How to Handle Push Notification Messages

In order to handle a push notification message, you need to add the following @Override below:

@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
    Map<String, String> data = remoteMessage.getData();
    String myCustomKey = data.get("my_custom_key");

    // Manage data
}

Note

If you press “Force Stop” in the application settings, then FCM will not deliver new messages to the app. The system will not start the app again until the user specifically asks for it by launching the app via the launcher icon.

To resume receiving push notifications on the device where the app was force stopped, simply relaunch the app.

Troubleshooting the Android SDK

If you're having trouble with the Android SDK, here's some more information to help troubleshoot the issue.

SDK Requirements

Review the following SDK requirements to make sure you're using the correct minimum versions of Android Studio, Java JDK, etc.:

  • Android Studio 2.3 or later
  • Android SDK Tools 25 or later
  • Android API Level 21 or later
  • Java JDK 8
  • Gradle for dependency management
  • A Webex Teams account and integration with the spark:all scope

View the System Logs

The Webex Teams Android SDK uses the Android system logger utility to collect log messages that will allow you to define problem areas when troubleshooting.

Use the Logcat command-line tool to collect, view, and filter all SDK logs. The Android SDK provides the option to display all messages or just the messages that indicate the most severe errors. Set the log level to verbose to display all errors. See Write and View Logs with Logcat for more information.

spark.setLogLevel(Spark.LogLevel.VERBOSE);

Firewall Ports

The Android SDK makes use of the following network ports. If you're encountering connection issues, make sure there aren't any firewalls blocking or preventing communication over these ports.

Service Protocol Port(s)
Messaging HTTPS 443
Notifications WebSocket 443
Calls HTTPS 443
Media RTP/SRTP over UDP/TCP 33434-33598, 8000-8100 or 33434 (shared port)

SDK Dependencies

For more information about dependencies of the Android SDK, please refer to their documentation:

App Crashes

If your app is crashing, running a stack trace may help you determine the root cause. Please see Android’s Diagnose the Crashes for more information about determining the cause of Android app crashes.

Getting Support

If you're stumped, contact the Webex Developer Support team for more help with the SDK.