react-native-android-call-kit

React Native kit to display incoming call UI, close app and unlock phone (Android only).

Usage no npm install needed!

<script type="module">
  import reactNativeAndroidCallKit from 'https://cdn.skypack.dev/react-native-android-call-kit';
</script>

README

React Native Android Call Kit

React Native kit to display incoming call UI, close app and unlock phone (Android only).

Installation

$ npm install react-native-android-call-kit

Addition installation step

In AndroidManifest.xml:

  • Add <activity android:name="com.incomingcall.UnlockScreenActivity" /> line between <application> tag.

  • Add

<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.DISABLE_KEYGUARD"/>
  • Also, it's recommend to put android:launchMode="singleInstance" in <activity android:name=".MainActivity"... tag to prevent duplicate activities.

For RN >= 0.60, it's done. Otherwise:

$ react-native link react-native-android-call-kit

Functions

Function Arguments Type Description
killApp Kills the application
unlockPhone Allows access to the app when locked screen
display Display incoming call UI
uuid (Required) string uuid v4
name (Required) string Calling username to be displayed in UI
avatar (Required) string Display avatar from URL
null Display default avatar
info (Required) string Text to be displayed in UI (e.g "Incoming Call")
timeout (Required) number dismiss the UI after timeout, if timeout is 0 UI is not dismissed
dismiss Dismiss incoming call UI
backToForeground Brings open app back to foreground
openAppFromHeadlessMode Use to open closed/killed app
getExtrasFromHeadlessMode Get Extras (isHeadless (boolean), uuid (string)) after running openAppFromHeadlessMode

Usage

In App.js:

import {useEffect} from 'react';
import {DeviceEventEmitter, Platform} from 'react-native';
import IncomingCall from 'react-native-android-call-kit';

// Listen to cancel and answer call events
useEffect(() => {
  if (Platform.OS === "android") {
    /**
     * App open from killed state (headless mode)
    */
    const payload = await IncomingCall.getExtrasFromHeadlessMode();
    console.log('launchParameters', payload);
    if (payload) {
      // Start call action here. You probably want to navigate to some CallRoom screen with the payload.uuid.
    }

    /**
     * App in foreground / background: listen to call events and determine what to do next
    */
    DeviceEventEmitter.addListener("endCall", payload => {
      // End call action here
      IncomingCall.killApp(); // kills the application
    });
    DeviceEventEmitter.addListener("answerCall", payload => {
      // Start call action here. You probably want to navigate to some CallRoom screen with the payload.uuid.
      IncomingCall.unlockPhone(); // unlock phone if locked
    });
  }
}, []);

In index.js or anywhere firebase background handler lies:

import messaging from '@react-native-firebase/messaging';
import {DeviceEventEmitter} from 'react-native';
import IncomingCall from 'react-native-android-call-kit';

messaging().setBackgroundMessageHandler(async remoteMessage => {
  // Receive remote message
  if (remoteMessage?.notification?.title === 'Incoming Call') {
    // Display incoming call activity.
    IncomingCall.display(
      'callUUIDv4', // Call UUID v4
      'Alex', // Username
      'https://www.aculab.com/images/logos/Aculab_logo.png', // Avatar URL
      // null, // display default avatar
      'Incoming Call', // Info text
      20000 // Timeout for end call after 20s
    );
  } else if (remoteMessage?.notification?.title === 'Missed Call') {
    // Terminate incoming activity. Should be called when call expired.
    IncomingCall.dismiss();
  }

  // Listen to headless action events
  DeviceEventEmitter.addListener("endCall", payload => {
    // End call action here
    IncomingCall.killApp(); // kills the application
  });
  DeviceEventEmitter.addListener("answerCall", (payload) => {
    console.log('answerCall', payload);
    if (payload.isHeadless) {
      // Called from killed state
      IncomingCall.openAppFromHeadlessMode(payload.uuid);
      IncomingCall.unlockPhone(); // unlock phone if locked
    } else {
      // Called from background state
      IncomingCall.backToForeground();
    }
  });
});