> ## Documentation Index
> Fetch the complete documentation index at: https://plivo.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Android SDK Reference

> Android SDK classes and methods — make and receive calls, push notifications

The Plivo Android SDK let you create applications capable of making and receiving calls. This document gives an overview of different classes and methods available in the Plivo Android SDK.

## New in Android SDK v2.0.0

1. Incoming call support through Firebase push notifications

2. SDK provided in both .aar file format

3. Android SDK support starting from Android 6.0 until latest Android 9

4. New example applications that cover all SDK features

## Applications Initialization

### Registering an endpoint

1. Declare or use user input for the SIP URI endpoint and password from the Plivo console.

   ```java theme={null}
    public final static String PLIVO_USERNAME = "Tatooine";
    public final static String PLIVO_PASSWORD = "Jabba";
   ```

2. Instantiate the Endpoint class

   * With options

   ```java theme={null}
    public static HashMap<String, Object> options = new HashMap<String, Object>()
        {
            {
                put("debug",true);
                put("enableTracking",true);
                put("maxAverageBitrate", 21000);
            }
        };
    Endpoint endpoint = Endpoint.newInstance(true, this, options);
   ```

   * Without options

   ```java theme={null}
    Endpoint endpoint = Endpoint.newInstance(true, this);
   ```

3. Log in with FCM token

   ```java theme={null}
    endpoint.login(username, password, fcmToken);
   ```

   Log in after fetching FCM token from Firebase.

4. Log in with FCM token and certificate ID

   ```java theme={null}
    endpoint.login(username, password, fcmToken, certificateId);
   ```

   Log in after fetching FCM token from Firebase and certificate ID from the Plivo console.

5. Log in with without FCM token

   ```java theme={null}
    endpoint.login(username, password, regTimeout);
   ```

For more information on the login methods, see [Endpoint class](#classes-and-methods).

## Examples of Basic Call Actions

### Make an outbound call

To make an outbound call, use these code snippets:

```java theme={null}
// Make an outbound call to a phone number
public final static String PHONE_NUMBER = "1415XXXXXXX";
Outgoing outgoing = endpoint.createOutgoingCall();
outgoing.call(PHONE_NUMBER);

// Make an outbound call to a phone number with extra headers
public final static String PHONE_NUMBER = "1415XXXXXXX";
Map<String, String> extraHeaders = new HashMap<>();
extraHeaders.put("X-PH-Header1", "12345");
extraHeaders.put("X-Ph-Header2", "34567");
outgoing = Phone.getInstance(this).createOutgoingCall();
outgoing.call(PHONE_NUMBER, extraHeaders);
```

### Receive a call

Implement EventListener on your class and override the onIncomingCall method using the command:

```java theme={null}
public void onIncomingCall(Incoming incoming) {
            incoming.answer();
}
```

<Note>
  **Note:** Also go through the section on [Setting Up Push Notification](/sdk/client/android/reference/#setting-up-push-notification) to implement incoming calls in an Android app.
</Note>

### Autoconnect when the network is available

Set NetworkChangeReceiver in the onCreate() method of your class to autoconnect when the network is available.

```java theme={null}
networkReceiver = new NetworkChangeReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
this.registerReceiver(networkReceiver, intentFilter);
```

## Configuration Parameters

| Attribute             | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                             | Allowed Values | Default Value |
| --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | ------------- |
| **debug**             | Enable log messages.                                                                                                                                                                                                                                                                                                                                                                                                                                                    | true/false     | false         |
| **enableTracking**    | Set to true if you want to get MediaMetrics events and enable call quality tracking.                                                                                                                                                                                                                                                                                                                                                                                    | true/false     | true          |
| **maxAverageBitrate** | You can use this parameter to control your application’s bandwidth consumption for calls.<br />A higher maxAverageBitrate value may result in more bandwidth consumption, but also better audio quality.<br />Lowering the maxAverageBitrate impacts call quality, as the audio is compressed to a greater extent to reduce bandwidth consumption.<br />This parameter applies only to calls using the Opus codec. Check out RFC-7587 section 7.1 for more information. | 8000 – 48000   | 48000         |

## Classes and Methods

### Class: Endpoint

Endpoint class allows you to register a Plivo SIP Endpoint, after which you can make and receive calls using it.

```java theme={null}
private Endpoint endpoint() {
  return endpoint != null? endpoint: (endpoint = Endpoint.newInstance(BuildConfig.DEBUG, this));
}
```

**Note:** Creates the endpoint objects:

```java theme={null}
public Endpoint(boolean debug, EventListener eventListener)
```

* @param debug — Setting this to true turns on the Plivo SDK debug logs. Otherwise, false.

* @param eventListener — Login, Call events Callback listener.

These are the methods available in the Endpoint class:

#### Method: login (String username, String password, String fcmToken, String certificateID)

```java theme={null}
public boolean login(String username, String password, String fcmToken, String certificateID)
```

##### Description:

This method is used to register an endpoint with FCM token and certificate ID. If the endpoint is successfully registered, a notification will be sent to the onLogin method of the EventListener. In case of failure, notification is sent to the onLoginFailed method of the EventListener.

<Note>
  **Note:** This is the recommended login method to enable incoming calls using push notifications.
</Note>

* username — The username of the endpoint created on Plivo
* password — The password of the endpoint created on Plivo
* fcmToken — Device token obtained from Firebase. The FCM token is needed to alert the user about incoming calls using Firebase push notifications.
* certificateID — Certificate ID created in the console after uploading push credentials. See [Manage Push credentials](#setting-up-push-notification).

##### Usage:

```java theme={null}
// retrieve FCM token, then log in
FirebaseInstanceId.getInstance().getInstanceId().addOnSuccessListener(this, instanceIdResult -> {
   String newToken = instanceIdResult.getToken();
   endpoint.login(usernameView.getText().toString(), passwordView.getText().toString(), newToken, certificateID);
});
```

#### Method: login(String username, String password, String fcmToken)

```java theme={null}
public boolean login(String username, String password, String fcmToken)
```

##### Description:

This method is used to register an endpoint with an FCM token. If the endpoint is successfully registered, a notification will be sent to the onLogin method of the EventListener. In case of a failure, notification is sent to the onLoginFailed method of the EventListener.

* username — The username of the endpoint created on Plivo

* password — The password of the endpoint created on Plivo

* fcmToken — Device token obtained from Firebase. The FCM token is needed to alert the user about incoming calls using Firebase push notifications.

##### Usage:

```java theme={null}
// retrieve FCM token, then log in
FirebaseInstanceId.getInstance().getInstanceId().addOnSuccessListener(this, instanceIdResult -> {
   String newToken = instanceIdResult.getToken();
   endpoint.login(usernameView.getText().toString(), passwordView.getText().toString(), newToken);
});
```

#### Method: login(String username, String password, int regTimeout)

```java theme={null}
public boolean login(String username, String password, int regTimeout)
```

##### Description:

This method is used to register an endpoint without an FCM token. If the endpoint is successfully registered, a notification will be sent to the onLogin method of the EventListener. In case of a failure, notification is sent to the onLoginFailed method of the EventListener.

<Note>
  **Note:** This login method has a limitation: Incoming calls may not work if the app goes to the background.
</Note>

* username — The username of the endpoint created on Plivo

* password — The password of the endpoint created on Plivo

* regTimeout — Seconds to reregister if the app is in the foreground. The default value is 600 seconds. The value range is from 120 sec to 86,400.

##### Usage:

```java theme={null}
endpoint.login(usernameView.getText().toString(), passwordView.getText().toString(),  600);
```

#### Method: relayVoipPushNotification(Map\<String, String> notification)

##### Description:

This method is used to forward the FCM notification data to the Plivo SDK. The onIncomingCall() method will be called after calling this function.

When the app is in the killed state and wakes up from the FCM notification, call login(username, password, deviceToken) before calling relayVoipPushNotification(remoteMessage.getData()).

```java theme={null}
notification - Notification data from FCM.
```

##### Usage:

When receiving a push notification from FCM, check whether the endpoint is logged in. If the endpoint is not logged in, call login(username, password, deviceToken) then call relayVoipPushNotification(remoteMessage.getData()).

##### Example:

```java theme={null}
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
   super.onMessageReceived(remoteMessage);
   if (endpoint.login(username, password, deviceToken)) {
       endpoint.relayVoipPushNotification(remoteMessage.getData());
   }
}
```

#### Method: logout

```java theme={null}
public boolean logout()
```

##### Description:

This method is used to unregister an endpoint.

##### Usage:

```java theme={null}
endpoint.logout();
```

#### Method: createOutgoingCall

```java theme={null}
public Outgoing createOutgoingCall ()
```

##### Description:

Calling this method returns an Outgoing object linked to the registered endpoint that can be used to make outbound calls. Calling this method on an unregistered PlivoEndpoint object returns null.

##### Usage:

```java theme={null}
public void getOutgoingCall() {
    Outgoing outgoing = endpoint.createOutgoingCall();
    return outgoing;
}
```

#### Method: resetEndpoint

```java theme={null}
public void resetEndpoint ()
```

##### Description:

If you choose to manually reset your endpoints and disable their WebSocket transport, you can use the resetEndpoint method as shown below:

##### Usage:

```java theme={null}
endpoint.resetEndpoint();
endpoint = Endpoint.newInstance(BuildConfig.DEBUG, this);
```

Ensure that you initialize the endpoint after reset, as shown above, or the WebSocket transport will not be reinitialized and your application will not be able to communicate with Plivo servers.

#### Method: submitCallQualityFeedback

```java theme={null}
public void submitCallQualityFeedback(String callUUID,Integer starRating, ArrayList<String> issueList ,
String comments , Boolean sendConsoleLogs, FeedbackCallback callback)
```

##### Description:

This method is used to submit call quality feedback after an end, reject, decline, or any other event of an outgoing or incoming call. If the feedback is successfully submitted, the onSuccess callback will be called. In case of any input validation error, the onValidationFail callback will be called. If the feedback submission fails, the onFailure callback will be called.

All three callbacks are implementations of the endpoint.FeedbackCallback interface.

* callUUID — Mandatory string parameter used to identify the call the feedback belongs to. You can get the callUUID for the last call using getLastCallUUID().
* starRating — Mandatory integer parameter with a value from 1 to 5. For a score from 1 to 4, the issues parameter is mandatory. It’s optional for a score of 5.
* issueList — IssueList is an Array and must have at least one of these reasons for a starRating value from 1 to 4 — 'AUDIO\_LAG', 'BROKEN\_AUDIO', 'CALL\_DROPPPED', 'CALLERID\_ISSUES', 'DIGITS\_NOT\_CAPTURED','ECHO', 'HIGH\_CONNECT\_TIME', 'LOW\_AUDIO\_LEVEL', 'ONE\_WAY\_AUDIO', 'ROBOTIC\_AUDIO', 'OTHERS'.
* Comments — Optional string attribute for users remarks, with a max length of 280 characters.
* sendConsoleLogs — Boolean optional parameter with default value false. Set this to true to let Plivo’s team collect and analyze Android SDK logs for a better understanding of the issue.
* callback — This is FeedbackCallback instance that accesses the onFailure, onSuccess, and onValidationFail callback methods.

##### Usage:

```java theme={null}
endpoint.submitCallQualityFeedback(callUUID, starRating, issueList, comments, sendConsoleLogs, new FeedbackCallback() {

    @Override
    public void onFailure(int statuscode) {
        Log._i_(_TAG_,"Status code : "+Integer._toString_(statuscode));
    }

    @Override
    public void onSuccess(String response) {
        Log._i_(_TAG_,"Success "+response);
    }

    @Override
    public void onValidationFail(String validationErrorMessage) {
        Log._i_(_TAG_,"Validation Failed : "+validationErrorMessage);
    }
});
```

#### Method: getCallUUID

```java theme={null}
public String getCallUUID();
```

##### Description:

Returns a string call UUID if a call is active, else returns null.

##### Usage:

```java theme={null}
String callUUID = endpoint.getCallUUID();
```

#### Method: getLastCallUUID

```java theme={null}
public String getLastCallUUID();
```

##### Description:

Returns the call UUID of the latest answered call. Useful if you want to send feedback for the last call.

##### Usage:

```java theme={null}
String callUUID = endpoint.getLastCallUUID();
```

### Class: Outgoing

The Outgoing class contains methods to make and control an outbound call.

```java theme={null}
import com.plivo.endpoint.Outgoing;
public Outgoing outgoing;

outgoing = new Outgoing(endpoint);
```

These are the methods available in the Outgoing class:

#### Method: call

```java theme={null}
public boolean call(String dest)
```

##### Description:

Use the Call method to make an outbound call. Use the SIP URI or a number to make a call.

##### Usage:

```java theme={null}
outgoing = Phone.getInstance(this).createOutgoingCall();
outgoing.call(phoneNumberText.getText().toString());
```

#### Method: mute

```java theme={null}
public boolean mute()
```

##### Description:

Calling this method on the Outgoing object mutes the call.

##### Usage:

```java theme={null}
if(outgoing!=null) {
   outgoing.mute();
}
```

#### Method: unmute

```java theme={null}
public boolean unmute()
```

##### Description:

Calling this method on the Outgoing object unmutes the call.

##### Usage:

```java theme={null}
if(outgoing!=null) {
   outgoing.unmute();
}
```

#### Method: sendDigits

```java theme={null}
public boolean sendDigits(String digit)
```

##### Description:

Calling this method on the Outgoing object with digits sends DTMF on that call. DTMF input supports only 0-9, \*, and #.

##### Usage:

```java theme={null}
if(outgoing!=null) {
   outgoing.sendDigits(dtmfText.getText().toString());
}
```

#### Method: hangup

```java theme={null}
public void hangup()
```

##### Description:

Calling this method on the Outgoing object disconnects the call.

##### Usage:

```java theme={null}
outgoing.hangup();
```

### Class: Incoming

The Incoming class contains methods to handle an incoming call. The public void onIncomingCall(Incoming incoming) eventListener will receive an object of this class.

These are the methods available in the Incoming class:

#### Method: answer

```java theme={null}
public void answer()
```

##### Description:

Use this method to answer an incoming call.

##### Usage:

```java theme={null}
incoming.answer();
```

#### Method: mute

```java theme={null}
public boolean mute()
```

##### Description:

Use this method to mute the call.

##### Usage:

```java theme={null}
if (incoming != null) {
   incoming.mute();
}
```

#### Method: unmute

```java theme={null}
public boolean unmute()
```

##### Description:

Use this method to unmute the call. Calling this method on an already unmuted call has no effect.

##### Usage:

```java theme={null}
if (incoming != null) {
   incoming.unmute();
}
```

#### Method: sendDigits

```java theme={null}
public boolean sendDigits(String digit)
```

##### Description:

Calling this method on the Incoming object with digits sends DTMF on that call. DTMF input supports only 0-9, \*, and #.

##### Usage:

```java theme={null}
if (incoming != null) {
   incoming.sendDigits(dtmfText.getText().toString());
}
```

#### Method: hangup

```java theme={null}
public void hangup()
```

##### Description:

Call this method on the Incoming object to disconnect the call.

##### Usage:

```java theme={null}
incoming.hangup();
```

#### Method: reject

```java theme={null}
public void reject()
```

##### Description:

Call this method to reject the incoming call.

##### Usage:

```java theme={null}
incoming.reject();
```

### Class: EventListener

These are the methods available in EventListener class:

#### Method: onLogin

```java theme={null}
public void onLogin()
```

##### Description:

This method is called when registration to an endpoint is successful.

##### Usage:

```java theme={null}
@Override
public void onLogin() {
   notifyLogin(true);
// notified that login is success and can proceed to other screens.
}
```

### Method: onLoginFailed

```java theme={null}
public void onLoginFailed()
```

##### Description:

This method is called when registration to an endpoint fails.

##### Usage:

```java theme={null}
@Override
public void onLoginFailed() {
   notifyLogin(false);
}
```

#### Method: onIncomingCall

```java theme={null}
public void onIncomingCall(Incoming incoming)
```

##### Description:

On an incoming call to a registered endpoint, this method receives an Incoming object.

##### Usage:

```java theme={null}
@Override
public void onIncomingCall(Incoming incoming) {
    // create call obj
    Call inCall = new Call.Builder()
            .setId(incoming.getCallId())
            .setType(Call.TYPE.INCOMING)
            .setState(Call.STATE.RINGING)
            .setContact(contactUtils.getContact(from(incoming.getFromContact(), incoming.getFromSip())))
            .setData(incoming)
            .build();
    addToCallStack(inCall);
    handler.postDelayed(ringingTimeoutRunnable, Call.CALL_RINGING_TIMEOUT);
    }
```

#### Method: onIncomingCallRejected

```java theme={null}
public void onIncomingCallRejected(Incoming incoming)
```

##### Description:

On an incoming call, if the call is rejected by the caller, this method will be triggered by the Incoming object.

##### Usage:

```java theme={null}
@Override
public void onIncomingCallRejected(Incoming incoming) {
   Call call = getCall(incoming.getCallId());
   if (call != null) {
       call.setState(Call.STATE.REJECTED);
       removeFromCallStack(call);
   }
   handler.removeCallbacks(ringingTimeoutRunnable);
}
```

#### Method: onIncomingCallHangup

```java theme={null}
public void onIncomingCallHangup(Incoming incoming)
```

##### Description:

On an incoming call, if the call is disconnected by the caller after being answered, this method will be triggered by the Incoming object.

##### Usage:

```java theme={null}
@Override
public void onIncomingCallHangup(Incoming incoming) {
   Call call = getCall(incoming.getCallId());
   if (call != null) {
       call.setState(Call.STATE.HANGUP);
       removeFromCallStack(call);
   }
   handler.removeCallbacks(ringingTimeoutRunnable);
}
```

#### Method: onIncomingDigitNotification

```java theme={null}
public void onIncomingDigitNotification(String digits)
```

##### Description:

On an active endpoint, this delegate is called with the digits received on the call.

<Note>
  **Note:** “\*” and “#” are received as “-6” and “-13” respectively on the SDK. Your app needs to explicitly convert these on this callback onIncomingDigitNotification(String digits).
</Note>

##### Usage:

```java theme={null}
@Override
public void onIncomingDigitNotification(String digit) {
   if (TextUtils.isEmpty(digit)) return;
   notifyDTMF(digit.equals("-6") ? "*" : digit.equals("-13") ? "#" : digit);
}
```

#### Method: onOutgoingCall

```java theme={null}
public void onOutgoingCall(Outgoing outgoing)
```

##### Description:

This delegate is called with the Outgoing object when an outgoing call is in progress before the ringing state.

##### Usage:

```java theme={null}
@Override
public void onOutgoingCall(Outgoing outgoing) {
   // create call obj local to your app or app logic when outgoing call is in progress.
   Call outCall = new Call.Builder()
           .setId(outgoing.getCallId())
           .setType(Call.TYPE.OUTGOING)
           .setState(Call.STATE.PROGRESS)
           .setContact(contactUtils.getContact(to(outgoing.getToContact())))
           .setData(outgoing)
           .build();
   addToCallStack(outCall);
}
```

#### Method: onOutogoingRinging

```java theme={null}
public void onOutogoingRinging(Outgoing outgoing)
```

##### Description:

This delegate is called with the Outgoing object when an outgoing call is in the ringing state.

##### Usage:

```java theme={null}
@Override
public void onOutgoingCallRinging(Outgoing outgoing) {
    Call call = getCall(outgoing.getCallId());
   if (call != null) call.setState(Call.STATE.RINGING);
   handler.postDelayed(ringingTimeoutRunnable, Call.CALL_RINGING_TIMEOUT);
}
```

#### Method: onOutgoingCallAnswered

```java theme={null}
public void onOutgoingCallAnswered(Outgoing outgoing)
```

##### Description:

This method is called with the Outgoing object when an outgoing call is answered.

##### Usage:

```java theme={null}
@Override
public void onOutgoingCallAnswered(Outgoing outgoing) {
   Call call = getCall(outgoing.getCallId());
   if (call != null) call.setState(Call.STATE.ANSWERED);
   handler.removeCallbacks(ringingTimeoutRunnable);
   notifyCallStackChange(call);
}
```

#### Method: onOutgoingCallHangup

```java theme={null}
public void onOutgoingCallHangup(Outgoing outgoing);
```

##### Description:

This method is triggered by the Outgoing object when an outgoing call is disconnected by the called number after the call has been answered.

##### Usage:

```java theme={null}
@Override
public void onOutgoingCallHangup(Outgoing outgoing) {
   Call call = getCall(outgoing.getCallId());
   if (call != null) {
       call.setState(Call.STATE.HANGUP);
       removeFromCallStack(call);
   }
   handler.removeCallbacks(ringingTimeoutRunnable);
}
```

#### Method: onOutgoingCallRejected

```java theme={null}
public void onOutgoingCallRejected(Outgoing outgoing);
```

##### Description:

This method is triggered by the Outgoing object when an outgoing call is rejected by the called number.

##### Usage:

```java theme={null}
@Override
public void onOutgoingCallRejected(Outgoing outgoing) {
   Call call = getCall(outgoing.getCallId());
   if (call != null) {
       call.setState(Call.STATE.REJECTED);
       removeFromCallStack(call);
   }
   handler.removeCallbacks(ringingTimeoutRunnable);
}
```

#### Method: onOutgoingCallInvalid

```java theme={null}
public void onOutgoingCallInvalid(Outgoing outgoing);
```

##### Description:

This method is triggered by the Outgoing object when an outgoing call is made to an invalid number.

##### Usage:

```java theme={null}
@Override
public void onOutgoingCallInvalid(Outgoing outgoing) {
   notifyCallStackChange(new Call.Builder().setState(Call.STATE.INVALID).build());
   handler.removeCallbacks(ringingTimeoutRunnable);
}
```

#### Method: mediaMetrics

##### Description:

For an ongoing call, if any of the below events are triggered, the MediaMetrics listener will be called with the values of the event in the mediaMetrics object. To enable this feature, set the enableTracking flag to true during endpoint initialization.

## MediaMetrics Events

| Events              | Description                                                                                                                                                         | Example                                                                                                                                                                                                                                                                                                                                          |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| high\_jitter        | When jitter is higher than 30 milliseconds for two out of the last three samples.<br />This event is generated individually for the local stream and remote stream. | `{ group: ‘network’, level: ‘warning’, type: ‘high_jitter’, active: true/false, // false when the value goes to normal level (last 2 out of 3 samples have jitter less than 30 ms) value: ‘<average jitter value>’, desc: ‘high jitter detected due to network congestion, can result in audio quality problems’, stream: ‘local \|\| remote’ }` |
| high\_rtt           | When round-trip time (RTT) is higher than 400 milliseconds for two out of the last three samples.                                                                   | `{ group: ‘network’, level: ‘warning’, type: ‘high_rtt’, active: true/false, // false when value goes to normal level (last 2 out of 3 samples have RTT less than 400 ms) value: ‘<average rtt value>’, desc: ‘high latency detected, can result in delay in audio’, stream: ‘None’ }`                                                           |
| high\_packetloss    | When the packet loss is > 10% for Opus and loss > 2% for PCMU.<br />This event is generated individually for the local stream and remote stream.                    | `{ group: ‘network’, level: ‘warning’, type: ‘high_packetloss’, active: true/false, // false when value goes to normal level value: ‘<average packet loss value>’, desc: ‘high packet loss is detected on media stream, can result in choppy audio or dropped call’, stream: ‘local \|\| remote’ }`                                              |
| low\_mos            | When sampled mean opinion score (MOS) is \< 3.5 for two out of the last three samples.                                                                              | `{ group: ‘network’, level: ‘warning’, type: ‘low_mos’, active: true/false, // false when value goes to normal level. value: ‘<current_mos_value>’, desc: ‘low Mean Opinion Score (MOS)’, stream: ‘None’ }`                                                                                                                                      |
| no\_audio\_received | When remote or local audio is silent.<br />This event is generated individually for the local stream and remote stream.                                             | `{ group: ‘audio’, level: ‘warning’, type: ‘no_audio_received’, active: true/false, // false when value goes to normal level value: ‘<current_value_in_dB>’, desc: ‘no audio packets received’ stream: ‘local \|\| remote’ }`                                                                                                                    |

## Setting Up Push Notification

This section explains how to receive incoming calls on the Plivo Android SDK v2 using Firebase. To receive an incoming call, you must:

1. Create a project on Firebase.

2. Register your app on Firebase.

3. Add the Firebase config file and SDK into your app.

4. Copy the Firebase service account token to the Plivo Dashoboard.

Let’s look at each of these steps in detail.

1. Create a project on Firebase
   * On the [Firebase console](https://console.firebase.google.com/?pli=1), click on Add project.
   * Add project name and click on Create project.
   <Frame>
     <img src="https://mintcdn.com/plivo/2TJ0wsMl3kmSwJSX/images/image_0.png?fit=max&auto=format&n=2TJ0wsMl3kmSwJSX&q=85&s=2d51746176c64c2fa1a7e87ae477216e" alt="" width="1440" height="822" data-path="images/image_0.png" />
   </Frame>
2. Register your app on Firebase
   * Go to the Android section of your Project home page.
   * Register your Android package on Firebase.
   <Frame>
     <img src="https://mintcdn.com/plivo/2TJ0wsMl3kmSwJSX/images/image_1.png?fit=max&auto=format&n=2TJ0wsMl3kmSwJSX&q=85&s=ba9d23db51fac59dd8b8fa62b1e5857a" alt="" width="1440" height="822" data-path="images/image_1.png" />
   </Frame>
   * Click on Register app.
3. Add a Firebase config file and SDK into your app
   * Download the Firebase google-services.json file.
   <Frame>
     <img src="https://mintcdn.com/plivo/2TJ0wsMl3kmSwJSX/images/image_2.png?fit=max&auto=format&n=2TJ0wsMl3kmSwJSX&q=85&s=fa1b337b0aa3b9194350bf2a6558fe12" alt="" width="1440" height="824" data-path="images/image_2.png" />
   </Frame>
   * Move the downloaded google-services.json into your Android app module root directory.
   * Click on Next.
   * Make the required changes to the Gradle of your Android app as instructed.
   <Frame>
     <img src="https://mintcdn.com/plivo/_fSpYHZS4fGpqS0Z/images/image_3.png?fit=max&auto=format&n=_fSpYHZS4fGpqS0Z&q=85&s=deef59d70c6484da8b635a79c03b0b1b" alt="" width="1440" height="820" data-path="images/image_3.png" />
   </Frame>
   * Wait for verification to be completed, then continue to the console.
   <Frame>
     <img src="https://mintcdn.com/plivo/_fSpYHZS4fGpqS0Z/images/image_4.png?fit=max&auto=format&n=_fSpYHZS4fGpqS0Z&q=85&s=f98b0cf6ecbde979d790af8d8057c6d2" alt="" width="1438" height="821" data-path="images/image_4.png" />
   </Frame>
4. Copy the Firebase service account token to the Plivo Dashoboard
   * From the project settings, under the Service accounts tab, download the private key and copy the token.
   <Frame>
     <img src="https://mintcdn.com/plivo/2TJ0wsMl3kmSwJSX/images/image8.png?fit=max&auto=format&n=2TJ0wsMl3kmSwJSX&q=85&s=470337726ce44adb323964de73006a5a" alt="" width="1440" height="820" data-path="images/image8.png" />
   </Frame>
   <Frame>
     <img src="https://mintcdn.com/plivo/2TJ0wsMl3kmSwJSX/images/image9.png?fit=max&auto=format&n=2TJ0wsMl3kmSwJSX&q=85&s=c2124be5903300d501addca1819d6c7c" alt="" width="1915" height="989" data-path="images/image9.png" />
   </Frame>
   * Go to Voice > [Mobile Push Credentials](https://cx.plivo.com/home) on the Plivo console, click on Update New Push Credential, and add the server key as type FCM.
   <Frame>
     <img src="https://mintcdn.com/plivo/2TJ0wsMl3kmSwJSX/images/image39.png?fit=max&auto=format&n=2TJ0wsMl3kmSwJSX&q=85&s=988b991e51641f927d568c2d97a68b4b" alt="" width="1440" height="571" data-path="images/image39.png" />
   </Frame>

## Resources

#### FAQ

1. Where can I see an example app that shows how to use the Android SDK to make calls?
   * The [PlivoAddressBook app](https://github.com/plivo/plivo-android-sdk2-examples/tree/master/PlivoAddressBook) shows full-fledged handling of the Plivo SDK features.
   * The [PlivoSimpleQuickStart app](https://github.com/plivo/plivo-android-sdk2-examples/tree/master/PlivoSimpleQuickStart) shows how to use the Android SDK with minimum code.
   * The [PlivoRegistration app](https://github.com/plivo/plivo-android-sdk2-examples/tree/master/PlivoRegistration) shows how to make outgoing call.
   * The [PlivoOutgoingCall app](https://github.com/plivo/plivo-android-sdk2-examples/tree/master/PlivoOutgoingCall) shows how to make an outgoing call.
   * The [PlivoIncomingCall app](https://github.com/plivo/plivo-android-sdk2-examples/tree/master/PlivoIncomingCall) shows how to receive incoming calls.
2. How can I file support tickets or report issues?<br />Please share support tickets or issues in the format below to help us debug issues quickly:

   * Description of your use case (like app backgrounded, on Wi-Fi/mobile data, lot of network fluctuations)

   * Plivo SDK Verbose Logs (Android application logs).
     * Pointers we will be looking for logs are like all the logs with the tag D/PlivoEndpoint or E/PlivoEndpoint
     * All SIP transactions, such as

       SIP/2.0 100 Trying

       Via: SIP/2.0/TLS 52.9.254.127:5061;received=52.9.254.127;branch=z9hG4bKc497.8ec67418aa83e5d7d0f48ad11f78026c.0

       Via: SIP/2.0/UDP 52.220.63.151:5080;rport=5080;received=52.220.63.151;branch=z9hG4bKKK6pv4Farvy9m

       Record-Route: \<sip:52.9.254.127:5061;transport=tls;lr;r2=on;ftag=NN36BrBcQ48pK;did=8c6.4611>

       Record-Route: \<sip:52.9.254.127;lr;r2=on;ftag=NN36BrBcQ48pK;did=8c6.4611>

       Call-ID: 62b89520-3410-11e9-90de-d1c5e59c76a4

       From: "android2181024115535" \<sip:+654321\@52.220.63.151>;tag=NN36BrBcQ48pK

       To: \<sip:android1181024115518\@52.9.254.127>

       CSeq: 725237 INVITE

       Content-Length: 0

   * Plivo callUUID (for instance, Call-ID:352231d3-3ea9-40c8-8259-e4843f5b02fc)

   * Plivo SDK version

   * Plivo SDK methods call flows, such as:
     * endpoint.login();
     * outgoing.callH(num, headers);

   * Android device version (for instance, Android 8.0.1 or Android 9.0)

   * Android device model (for example, Samsung Galaxy A8 Plus)<br /><br />Attach these details when you create a new ticket with Plivo support.

#### Best Practices

1. Don’t use the deprecated methods, because they will be prone to crashes NoMethodError when removed in the future.

2. Use the deviceToken while logging in to get an incoming call via push notification instead of using the background service to run forever in the background and watch for incoming calls.
