The Cisco Webex™ Android SDK
The Cisco Webex Android SDK makes it easy to integrate secure and convenient Cisco Webex messaging and calling features in your Android apps.
This SDK is built with Android SDK Tools 27 and requires Android API Level 21 or later.
Assuming you already have an Android project, e.g. MyWebexApp, for your Android app, here are the steps to integrate the Cisco Webex Android SDK into your project using Gradle:
-
Add the following repository to your top-level
build.gradle
file:allprojects { repositories { jcenter() maven { url 'https://devhub.cisco.com/artifactory/webexsdk/' } } }
-
Add the
webex-android-sdk
library as a dependency for your app in thebuild.gradle
file:dependencies { compile('com.ciscowebex:androidsdk:2.6.0@aar', { transitive = true }) }
-
Enable multidex support for your app:
android { defaultConfig { multiDexEnabled true } }
-
Exclude rxjava.properties in your packagingOptions :
packagingOptions { exclude 'META-INF/rxjava.properties' }
To use the SDK, you will need Cisco Webex integration credentials. If you do not already have a Cisco Webex account, visit the Cisco Webex for Developers portal to create your account and register an integration. Your app will need to authenticate users via an OAuth grant flow for existing Cisco Webex users or a JSON Web Token for guest users without a Cisco Webex account.
See the Android SDK area of the Cisco Webex for Developers site for more information about this SDK.
Here are some examples of how to use the Android SDK in your app.
-
Create a new
Webex
instance using Webex ID authentication (OAuth-based):String clientId = "YOUR_CLIENT_ID"; String clientSecret = "YOUR_CLIENT_SECRET"; String scope = "spark:all"; String redirectUri = "Webexdemoapp://response"; OAuthWebViewAuthenticator authenticator = new OAuthWebViewAuthenticator(clientId, clientSecret, scope, redirectUri); Webex webex = new Webex(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"); } } }); }
-
Create a new
Webex
instance using Guest ID authentication (JWT-based):JWTAuthenticator authenticator = new JWTAuthenticator(); Webex webex = new Webex(activity.getApplication(), authenticator); if (!authenticator.isAuthorized()) { authenticator.authorize(myJwt); }
-
Register the device to Webex platform:
webex.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 } } });
-
Create a new Cisco Webex space, add users to the space, and send a message:
// Create a Cisco Webex space: webex.spaces().create("Hello World", null, new CompletionHandler<Space>() { @Override public void onComplete(Result<Space> result) { if (result.isSuccessful()) { Space space = result.getData(); } else { WebexError error = result.getError(); } } }); // Add a user to a space: webex.memberships().create(spaceId, null, "[email protected]", true, new CompletionHandler<Membership>() { @Override public void onComplete(Result<Membership> result) { if (result.isSuccessful()) { Membership membership = result.getData(); } else { WebexError error = result.getError(); } } }); // Send a message to a space: webex.messages().postToSpace(spaceId, Message.Text.html("<strong>Hello</strong>", "Hello"), null, null, new CompletionHandler<Message>() { @Override public void onComplete(Result<Message> result) { if (result.isSuccessful()) { Message message = result.getData(); } else { WebexError error = result.getError(); } } });
-
Make an outgoing call:
webex.phone().dial("[email protected]", 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 { WebexError error = result.getError(); } } });
-
Receive a call:
webex.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 { WebexError error = result.getError(); } } }); } });
-
Make an space call:
webex.phone().dial(spaceId, MediaOption.audioVideoSharing(new Pair<>(localView,remoteView),shareView), new CompletionHandler<Call>() { @Override public void onComplete(Result<Call> result) { Call call = result.getData(); if (call != null) { call.setObserver(new CallObserver() { @Override public void onConnected(Call call) { } //... @Override public void onCallMembershipChanged(CallMembershipChangedEvent callMembershipChangeEvent) { CallMembership membership = callMembershipChangeEvent.getCallMembership(); if (callMembershipChangeEvent instanceof MembershipJoinedEvent) { } else if (callMembershipChangeEvent instanceof MembershipLeftEvent) { } else if (callMembershipChangeEvent instanceof MembershipDeclinedEvent) { } else if (callMembershipChangeEvent instanceof MembershipSendingVideoEvent) { } else if (callMembershipChangeEvent instanceof MembershipSendingAudioEvent) { } else if (callMembershipChangeEvent instanceof MembershipSendingSharingEvent) { } } }); } else { WebexError error = result.getError(); } } });
-
Receive screen share:
webex.phone().dial(spaceId, MediaOption.audioVideoSharing(new Pair<>(localView,remoteView),shareView), new CompletionHandler<Call>() { @Override public void onComplete(Result<Call> result) { Call call = result.getData(); if (call != null) { call.setObserver(new CallObserver() { @Override public void onConnected(Call call) { } //... @Override public void onMediaChanged(MediaChangedEvent mediaChangedEvent) { if (mediaChangedEvent instanceof RemoteSendingSharingEvent) { if (((RemoteSendingSharingEvent) mediaChangedEvent).isSending()) { mediaChangedEvent.getCall().setSharingRenderView(shareView); } else if (!((RemoteSendingSharingEvent) mediaChangedEvent).isSending()) { mediaChangedEvent.getCall().setSharingRenderView(null); } } } }); } else { WebexError error = result.getError(); } } });
-
Start/stop sharing screen:
activeCall.startSharing(r -> Ln.d("startSharing result: " + r)); boolean isSharing = activeCall.isSendingSharing(); activeCall.stopSharing(r -> Ln.d("stopSharing result: " + r));
-
Post a message
webex.message().postToPerson( EmailAddress.fromString("[email protected]"), Message.Text.markdown("**Hello**", "<strong>Hello</strong>", "Hello"), files, new CompletionHandler<Message>() { @Override public void onComplete(Result<Message> result) { if (result.isSuccessful()) { // message sent success ... } else { // message sent failed ... } } }));
-
Post a threaded message
webex.message().postToPerson( EmailAddress.fromString("[email protected]"), Message.Text.markdown("**Hello**", "<strong>Hello</strong>", "Hello"), files, parentMessage, new CompletionHandler<Message>() { @Override public void onComplete(Result<Message> result) { if (result.isSuccessful()) { // message sent success ... } else { // message sent failed ... } } }));
-
Receive a message
webex.message().setMessageObserver( new MessageObserver() { void onEvent(MessageEvent event) { if (event instanceof MessageReceived) { Message message = event.getMessage(); // new message arrived if(message.getParent != null){ // threaded message } } else if (event instanceof MessageDeleted) { // message deleted } } } );
-
Send Read Receipts
//Mark all exist messages in space as read webex.message().markAsRead(spaceId); //Mark exist messages before pointed message(include) in space as read webex.message().markAsRead(spaceId, messageId);
-
Multi-Stream to receive more video streams
activeCall.setMultiStreamObserver(new MultiStreamObserver() { @Override public void onAuxStreamChanged(AuxStreamChangedEvent event) { if (event instanceof MultiStreamObserver.AuxStreamOpenedEvent) { if ((MultiStreamObserver.AuxStreamOpenedEvent)event.isSuccessful()) { // success to open a stream ... } else { // fail to open a stream ... } } else if (event instanceof MultiStreamObserver.AuxStreamClosedEvent) { if ((MultiStreamObserver.AuxStreamClosedEvent)event.isSuccessful()) { // success to close a stream ... } else { // fail to close a stream ... } } else if (event instanceof MultiStreamObserver.AuxStreamSendingVideoEvent) { ... } else if (event instanceof MultiStreamObserver.AuxStreamPersonChangedEvent) { ... } else if (event instanceof MultiStreamObserver.AuxStreamSizeChangedEvent) { ... } } @Override public View onAuxStreamAvailable() { // should return a MediaRenderView for rendering return mediaRenderView; } @Override public View onAuxStreamUnavailable() { // should return a MediaRenderView to stop rendering or return null to let SDK handle it return null; } });
-
Set MembershipObserver to receive Membership events
webex.memberships().setMembershipObserver(new MembershipObserver() { @Override public void onEvent(MembershipEvent event) { //The WebexEventPayload. WebexEvent.Payload payload = event.getPayload(); ... if (event instanceof MembershipCreated) { //The event when a new membership has added to a space. ... } else if (event instanceof MembershipDeleted) { //The event when a membership has removed from a space. ... } else if (event instanceof MembershipUpdated) { //The event when a membership moderator status changed ... }else if (event instanceof MembershipSeen){ //The event when a user has sent a read receipt ... } } });
-
Set SpaceObserver to receive Space events
webex.spaces().setSpaceObserver(new SpaceObserver() { @Override public void onEvent(SpaceEvent event) { //The WebexEventPayload. WebexEvent.Payload payload = event.getPayload(); if (event instanceof SpaceCreated){ //The event when a new space was created ... }else if (event instanceof SpaceUpdated){ //The event when a space was changed (usually a rename) ... } } });
-
Get space meeting details
webex.spaces().getMeeting(spaceId, new CompletionHandler<SpaceMeeting>() { @Override public void onComplete(Result<SpaceMeeting> result) { if (result.isSuccessful()){ SpaceMeeting spaceMeeting = result.getData(); ... } } });
-
Get read status of a space
webex.spaces().getWithReadStatus(spaceId, new CompletionHandler<SpaceReadStatus>() { @Override public void onComplete(Result<SpaceReadStatus> result) { if (result.isSuccessful()){ SpaceReadStatus spaceReadStatus = result.getData(); ... } } });
-
Join password-protected meetings
mediaOption.setModerator(boolean moderator); mediaOption.setPin(String pin);
-
Change the video layout during a call
activeCall.setVideoLayout(MediaOption.VideoLayout layout);
-
Specify how the remote video adjusts its content to be render in a view
activeCall.setRemoteVideoRenderMode(VideoRenderMode mode);
-
Change the max sending fps for video
webex.phone().setAdvancedSetting(new VideoMaxTxFPS(int value));
-
Enable(disable) android.hardware.camera2
webex.phone().setAdvancedSetting(new VideoEnableCamera2(boolean enable));
-
Whether the app can continue video streaming when app in background
webex.phone().enableBackgroundStream(boolean enable);
-
Get a list of spaces that have ongoing call
webex.spaces().listWithActiveCalls(r -> {});
-
Check if the message mentioned everyone in space
message.isAllMentioned()
-
Get all people mentioned in the message
message.getMentions()
The purpose of this guide is to help you to migrate from Cisco Spark Android SDK to Cisco Webex Android SDK.
Assuming you already have an Android project with Spark Android SDK integrated. For your Android app, here are the steps to migrate to use Webex Android SDK:
-
Change the maven repository url in your top-level
build.gradle
file:allprojects { repositories { jcenter() maven { // url 'https://devhub.cisco.com/artifactory/sparksdk/' url 'https://devhub.cisco.com/artifactory/webexsdk/' } } }
-
Update the library dependency for your app in the
build.gradle
file:dependencies { // compile('com.ciscospark:androidsdk:1.4.0@aar', { // transitive = true // }) implementation('com.ciscowebex:androidsdk:2.6.0@aar', { transitive = true }) }
Here are API changes list from Spark Android SDK to Webex Android SDK.
Description | Spark Android SDK | Webex Android SDK |
---|---|---|
Package name | com.ciscospark.androidsdk | com.ciscowebex.androidsdk |
Create a new instance | Spark spark = new Spark(application, authenticator) | Webex webex = new Webex(application, authenticator) |
Get error response | SparkError error = result.getError() | WebexError error = result.getError() |
Rename Room to Space | spark.rooms().get(roomId, CompletionHandler< Room > handler) | webex.spaces().get(spaceId, CompletionHandler< Space > handler) |
Pull requests welcome. To suggest changes to the SDK, please fork this repository and submit a pull request with your changes. Your request will be reviewed by one of the project maintainers.
© 2016-2020 Cisco Systems, Inc. and/or its affiliates. All Rights Reserved.
See LICENSE for details.