Suggestions

close search

Getting started with Stringee Call API using Android SDK

Step 1: Prepare

Before you use Stringee Call API to make or receive a call:

  1. Sign up for a Stringee account free here: https://developer.stringee.com/account/register
  2. Create a project on Stringee Dashboard.

Stringee create project

  1. Buy a number (Option): For app-to-phone, phone-to-app calling, buy a number from Dashboard. If you only need app-to-app calling, skip this step.

Stringee buy number

  1. Configure answer_url

For more information on answer_url, read Stringee Call API Overview. You can view answer_url sample code here: https://github.com/stringeecom/server-samples/tree/master/answer_url

Stringee project answer_url

If you do not have a answer_url, to speed things up you can use the following answer_url:

https://v1.stringee.com/dev_urls/answer_url/from_internal-test.php

(Source code here: https://github.com/stringeecom/server-samples/blob/master/answer_url/php/answer_url-from_internal.php)

But in a production application, you should use your own answer_url.

Stringee number answer_url

If you do not have a answer_url, to speed things up you can use the following answer_url:

https://v1.stringee.com/dev_urls/answer_url/from_external-test.php?userId=USER_ID

The call is routed to Your App which authenticated by USER_ID

(Source code here: https://github.com/stringeecom/server-samples/blob/master/answer_url/php/answer_url-from_external.php)

But in a production application, you should use your own answer_url.

Then, the best way to learn how to uses Stringee Call API is to follow the following steps:

Step 2: Creating a new project

Stringee SDK is designed to be used with Android Studio

1. Open Android Studio and select New Project from the File menu.
2. Set the minimum SDK for the app to be API 15 (Android 4.0.3 ICE_CREAM_SANDWICH).
3. Click through the wizard, ensuring that Empty Activity is selected. Leave the Activity Name set to MainActivity, and leave the Layout Name set to activity_main.

Step 3: Adding the Stringee SDK

Stringee Android SDK is distributed as an AAR and can be added to your project by referencing the AAR remotely with Maven.

  1. Navigate to your build.gradle at the project level and include the following:

Stringee jcenter

allprojects {
    repositories {
        jcenter()
    }
}
  1. Navigate to your build.gradle at the app level and include the following:

Stringee dependencies

android {
    ...
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}
dependencies {    
    compile 'com.stringee.sdk.android:stringee-android-sdk:1.3.8'
}

Step 4: Permissions and proguard

The Stringee Android SDK requires some permissions from your app's AndroidManifest.xml file:

// for internet access
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
// for audio access
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
// for camera access
<uses-permission android:name="android.permission.CAMERA" />

If your project uses ProGuard, you may have to add the following settings to the ProGuard configuration file to ensure Stringee builds correctly:

-dontwarn org.webrtc.**
-keep class org.webrtc.** { *; }
-keep class com.stringee.** { *; }

Step 5: Setting up authentication

In order to connect to Stringee Server, you will need access to the authentication credential: access_token. In production application, the access_token should be generated by your server described here: Client authentication, sample code generates access token here: https://github.com/stringeecom/server-samples/tree/master/access_token.

But to speed things up we will just hard code the value for now:

  1. In the MainActivity class, declare a variable to store the access_token.

    public class MainActivity extends AppCompatActivity {
    
    private String token;
  2. Adjust the code by hard coding the value for the token:

To do this, go to Dashboard -> Tools -> Generate Access token and generates an access_token.

Step 6: Connecting

Next, we will connect to Stringee Server. You must do this before you can make or answer a call.

  1. Add a StringeeClient property to the MainActivity class.
    private StringeeClient client;

    The StringeeClient class is defined in Stringee SDK. It includes methods interacting with Stringee Server.

  2. Instantiate the StringeeClient object and call its connect(token) method:
    client = new StringeeClient(this);
    client.connect(token);
  3. To interact with Stringee Server connection, you will need register a StringeeConnectionListener interface with StringeeClient object before connecting.

    client.setConnectionListener(new StringeeConnectionListener() {
    @Override
    public void onConnectionConnected(StringeeClient stringeeClient, boolean isReconnecting) {
    }
    
    @Override
    public void onConnectionDisconnected(StringeeClient stringeeClient, boolean isReconnecting) {
    
    }
    
    @Override
    public void onIncomingCall(StringeeCall stringeeCall) {
    
    }
    
    @Override
    public void onConnectionError(StringeeClient stringeeClient, StringeeError stringeeError) {
    
    }
    
    @Override
    public void onRequestNewToken(StringeeClient stringeeClient) {
    
    }
    
    @Override
    public void onCustomMessage(String from, JSONObject msg) {
    
    }
    });        
    • When the client connects to Stringee Server, the onConnectionDisconnected(StringeeClient stringeeClient, boolean isReconnecting) method is called.
    • When the client disconnects to Stringee Server, the onConnectionDisconnected(StringeeClient stringeeClient, boolean isReconnecting) method is called
    • When the client fails to connect to Stringee Server, the onConnectionError(StringeeClient stringeeClient, StringeeError stringeeError) method is called.
    • When the token is expired, the onRequestNewToken(StringeeClient stringeeClient) is called. You will need re-generate a new token and connect again.
    • When the client have an incoming call, the onIncomingCall(StringeeCall stringeeCall) method is called.

Step 7: Making a call

After connects to Stringee Server, we want to make a call:

  1. Create OutgoingCallActivity class to display the outgoing call screen.
  2. Add a stringeeCall property to the OutgoingCallActivity class:
    private StringeeCall stringeeCall;
  3. Modify the implementation of the onCreate method in OutgoingCallActivity class to include code to make a call:
    stringeeCall = new StringeeCall(MainActivity.this, client, from, to);
    stringeeCall.makeCall();
    • client: the StringeeClient object that has been initiated from MainActivity. Make sure the client has already connected to Stringee Server.
    • from: is the caller's id.
    • to: is the callee's id. A Stringee call is a voice call by default. If you want to make a video call, you must call the setVideoCall(true) method after instantiating a Stringeecall object.
      stringeeCall = new StringeeCall(MainActivity.this, client, from, to);
      stringeeCall.setVideoCall(true);
      stringeeCall.makeCall();
  4. Handle the call type

The type of the outgoing call (app-to-app or app-to-phone) is decided by Your Server via the project's answer_url. So you can definitely do it by yourself. But we provide an easy way that help you implement quickly by calling:

stringeeCall.setCustom(custom);

'custom' is a customizable text that be sent to Your Server via the project's answer_url. You can set it as: {'type': 'app-to-app'}, {'type':'app-to-phone'} or any other texts you want. Your Server will check this text to determine whether the call is app-to-app or app-to-phone.

  1. Implement the StringeeCall.StringeeCallListener interface to interact with the call:

    stringeeCall.setCallListener(new StringeeCall.StringeeCallListener() {
    @Override
    public void onSignalingStateChange(final StringeeCall call, final StringeeCall.SignalingState signalingState, String reason, int sipCode, String sipReason) {
    }
    
    @Override
    public void onError(StringeeCall stringeeCall, int code, String description) {
    
    }
    
    @Override
    public void onHandledOnAnotherDevice(StringeeCall stringeeCall, StringeeCall.SignalingState signalingState, String description) {
    
    }
    
    @Override
    public void onMediaStateChange(StringeeCall stringeeCall, StringeeCall.MediaState mediaState) {
    }
    
    @Override
    public void onLocalStream(final StringeeCall stringeeCall) {
    }
    
    @Override
    public void onRemoteStream(final StringeeCall stringeeCall) {
    }
    
    @Override
    public void onCallInfo(StringeeCall stringeeCall, final JSONObject callInfo) {
    }
    });
    • When the client fails to make a call, the onError(StringeeCall stringeeCall, int code, String description) method is invoked.
    • When the client makes a call successfully, the call will walk through a lot of states such as: calling, ringing, answered, ended, busy... Each time the call's state, the onSignalingStateChange(final StringeeCall call, final StringeeCall.SignalingState signalingState, String reason, int sipCode, String sipReason) method is invoked.
    • When the call's media stream is connected or disconnected, the onMediaStateChange(StringeeCall stringeeCall, StringeeCall.MediaState mediaState) method is invoked.
    • When the call is handled on another device, the onHandledOnAnotherDevice(StringeeCall stringeeCall, StringeeCall.SignalingState signalingState, String description) method is invoked. A call is actually established when it's answered and the media's state is MediaState.CONNECTED.

Step 8: Answering a call

We want clients to be able to answer an incoming call:

  1. Create IncomingCallActivity class to display the incoming call screen.
  2. Modify the implementation of the onIncomingCall(StringeeCall stringeeCall) method and include code to navigate to the IncomingCallActivity.
    @Override
    public void onIncomingCall(StringeeCall stringeeCall) {
    callsMap.put(stringeeCall.getCallId(), stringeeCall);
    Intent intent = new Intent(MainActivity.this, IncomingCallActivity.class);
    intent.putExtra("call_id", stringeeCall.getCallId());
    startActivity(intent);
    }

    Pass the call id to the IncomingCallActivity class.

  3. Add a stringeeCall property to the IncomingCallActivity class:
    private StringeeCall stringeeCall;
  4. Get StringeeCall from calls map:
    
    String callId = getIntent().getStringExtra("call_id");
    stringeeCall = callsMap.get(callId);
  5. Initialize the answer:
    stringeeCall.initAnswer(context, client);
  6. Answer and start the conversation:
    stringeeCall.answer();

Step 9: Hanging up

Terminate a call and release resources:

stringeeCall.hangup();

Step 10: Displaying video

The Stringee Android SDK exposes videos of caller and callee as View objects. You can add these as children of ViewGroup objects in your app. This sample app will use FrameLayout objects (which extend ViewGroup) as containers for the caller and callee views:

  1. Open the app/res/layout/activity_outgoing_call.xml file and include the following:
<FrameLayout
    android:id="@+id/v_remote"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

<FrameLayout
    android:id="@+id/v_local"
    android:layout_width="80dp"
    android:layout_height="120dp"
    android:layout_alignParentRight="true"        
    android:layout_margin="10dp" />
  1. Declare mLocalViewContainer and mRemoteViewcontainer as properties of OutgoingCallActivity class.

    private FrameLayout mLocalViewContainer;
    private FrameLayout mRemoteViewContainer;
  2. Then, initialize these layout view objects

    mLocalViewContainer = (FrameLayout) findViewById(R.id.v_local);
    mRemoteViewContainer = (FrameLayout) findViewById(R.id.v_remote);
  3. Register the StringeeCall.StringeeCallListener interface as described in 7.4

  4. Modify the implementation code of the onLocalStream(final StringeeCall stringeeCall) method to display caller's video (local media stream):
    runOnUiThread(new Runnable() {
    @Override
    public void run() {
        if (stringeeCall.isVideoCall()) {
            mLocalViewContainer.addView(stringeeCall.getLocalView());
            stringeeCall.renderLocalView(true);
        }
    }
    });

    onLocalStream(final StringeeCall stringeeCall) method runs in background thread. So in order to interact with UI components from this method, your code must run in UI thread.

  5. Modify the implementation code of the onRemoteStream(StringeeCall stringeeCall) method to display callee's video (remote media stream):
    runOnUiThread(new Runnable() {
    @Override
    public void run() {
        if (stringeeCall.isVideoCall()) {
            mRemoteViewContainer.addView(stringeeCall.getRemoteView());
            stringeeCall.renderRemoteView(false);
        }
    }
    });

    Step 11: Running the app

    Now that your code is complete, you can run the app with your device. You can view a completed version of this sample app on GitHub: https://github.com/stringeecom/android-sdk-samples/tree/master/OneToOneCallSample