Giter VIP home page Giter VIP logo

react-native-incall-manager's Introduction

react-native-incall-manager

npm version npm downloads

Handling media-routes/sensors/events during a audio/video chat on React Native

Purpose:

The purpose of this module is to handle actions/events during a phone call (audio/video) on react-native, ex:

  • manage devices events like wired-headset plugged, proximity sensors and expose to javascript.
  • automatically route audio to proper device based on events and platform API.
  • toggle speaker or microphone on/off, toggle flash light on/off (not implemented yes)
  • play ringtone/ringback/dtmftone

basically, it is a telecommunication module which handle most of requirements when making/receiving/talking to a call.

This module is desinged to work with react-native-webrtc you can find demo here: https://github.com/oney/RCTWebRTCDemo

Installation:

from npm package: npm install react-native-incall-manager
from git package: npm install git://github.com/zxcpoiu/react-native-incall-manager.git

=================================================== ####android:

After install, you can use rnpm (npm install rnpm -g) to link android.
use rnpm link react-native-incall-manager to link or manually if you like.

optional sound files on android if you want to use bundled ringtone/ringback/busytone sound instead of system sound

We use android support library v4 to check/request permissions.
You should add compile "com.android.support:support-v4:23.0.1" in $your_project/android/app/build.gradle dependencies on android.

put files in android/app/src/main/res/raw and rename file correspond to sound type:

incallmanager_busytone.mp3  
incallmanager_ringback.mp3  
incallmanager_ringtone.mp3 

on android, as long as your file extension supported by android, this module will load it.

===================================================

####ios:

since ios part written in swift and it doesn't support static library yet.
before that, you should add this project manually:

  • Add files in to your project:

    1. Open your project in xcode
    2. find your_project directory under your project's xcodeproject root. ( it's a sub-directoory, not root xcodeproject itself )
    3. you can do either:
    • directly drag your node_modules/react-native-incall-manager/ios/RNInCallManager/ into it.
    • right click on your_project directory, add files to your project and add node_modules/react-native-incall-manager/ios/RNInCallManager/
    1. on the pou-up window, uncheck Copy items if needed and select Added folders: Create groups then add it. you will see a new directory named RNInCallmanager under your_project directory.
  • Setup Objective-C Bridging Header:

    1. click your project's xcodeproject root, go to build setting and search Objective-C Bridging Header
    2. set you header location, the default path is: ReactNativeProjectRoot/ios/, in this case, you should set ../node_modules/react-native-incall-manager/ios/RNInCallManager/RNInCallManager-Bridging-Header.h

optional sound files on android if you want to use bundled ringtone/ringback/busytone sound instead of system sound

  1. add files into your_project directory under your project's xcodeproject root. ( or drag into it as described above. )
  2. check copy file if needed
  3. make sure filename correspond to sound type:
incallmanager_busytone.mp3
incallmanager_ringback.mp3 
incallmanager_ringtone.mp3 

on ios, we only support mp3 files currently.

Usage:

This module implement a basic handle logic automatically, just:

import InCallManager from 'react-native-incall-manager';

// --- start manager when the chat start based on logics of your app 
// On Call Established:
InCallManager.start({media: 'audio'}); // audio/video, default: audio

// ... it will also register and emit events ...

// --- On Call Hangup:
InCallManager.stop();
// ... it will also remote event listeners ...

if you want to use ringback:

// ringback is basically for OUTGOING call. and is part of start().

InCallManager.start({media: 'audio', ringback: '_BUNDLE_'}); // or _DEFAULT_ or _DTMF_
//when callee answered, you MUST stop ringback explicitly:
InCallManager.stopRingback();

if you want to use busytone:

// busytone is basically for OUTGOING call. and is part of stop()
// If the call failed or callee are busing,
// you may want to stop the call and play busytone
InCallManager.stop({busytone: '_DTMF_'}); // or _BUNDLE_ or _DEFAULT_

if you want to use ringtone:

// ringtone is basically for INCOMING call. it's independent to start() and stop()
// if you receiving an incoming call, before user pick up,
// you may want to play ringtone to notify user.
InCallManager.startRingtone('_BUNDLE_'); // or _DEFAULT_ or system filename with extension

// when user pickup
InCallManager.stopRingtone();
InCallManager.start();

// or user hangup
InCallManager.stopRingtone();
InCallManager.stop();

also can interact with events if you want: see API section.

import { DeviceEventEmitter } from 'react-native';

DeviceEventEmitter.addListener('Proximity', function (data) {
    // --- do something with events
});

About Permission:

since version 1.2.0, two functions and a property were added:

// --- function
async checkRecordPermission() // return promise
async requestRecordPermission() // return promise

// --- property
recordPermission = 'unknow' or 'granted' or 'denied', default is 'unknow'

After incall-manager initialized, it will check current state of record permission and set to recordPermission property. so you can just write below code in your ComponentDidMount like:

if (InCallManager.recordPermission !== 'granted') {
    InCallManager.requestRecordPermission()
    .then((requestedRecordPermissionResult) => {
        console.log("InCallManager.requestRecordPermission() requestedRecordPermissionResult: ", requestedRecordPermissionResult);
    })
    .catch((err) => {
        console.log("InCallManager.requestRecordPermission() catch: ", err);
    });
}

We use android support library v4 to check/request permissions.
You should add compile "com.android.support:support-v4:23.0.1" in $your_project/android/app/build.gradle dependencies on android.

NOTE for android:

React Native does not officially support api 23 currently ( it is on api 22 now. see: RN known issues) and android supports request permission at runtime since api 23, so it will always return 'granted' immediately after calling checkRecordPermission() or requestRecordPermission().

If you really need the functionality, you can do the following to make them work but at your own risk:
( I've tested it though, but who knows :) )

Step 1: change your targetSdkVersion to 23 in $your_project/android/app/build.gradle
Step 2: override onRequestPermissionsResult in your MainActivity.java like:

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        InCallManagerPackage.onRequestPermissionsResult(requestCode, permissions, grantResults);
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }

then you can test it on android 6 now.

Another thing you should know is:

If you change targetSdkVersion to 23, the red box which React Native used to display errors in development mode requires permission Draw Over Other Apps.
So in development mode, you should manually grant permission in app settings on your device or declare android.permission.SYSTEM_ALERT_WINDOW in your manifest.
You don't have to do this in release mode since there are no red box.

checkout this awesome project: react-native-android-permissions by @lucasferreira for more information.

Automatic Basic Behavior:

on start:

  • store current settings, set KeepScreenOn flag = true, and register some event listeners.
  • if media type is audio, route voice to earpiece, otherwise route to speaker.
  • audio will enable proximity sensor which is disabled by default if media=video
  • when proximity detect user closed to screen, turn off screen to avoid accident touch and route voice to earpiece.
  • when newly external device plugged, such as wired-headset, route audio to external device.
  • optional play ringback

on stop:

  • set KeepScreenOn flag = false, remote event listeners, restore original user settings.
  • optional play busytone

Custom Behavior:

you can custom behavior use API/events exposed by this module. see API section.

note: ios only supports auto currently.

API:

Methods

Method android ios description
start({media: ?string, auto: ?boolean, ringback: ?string}) ๐Ÿ˜„ ๐Ÿ˜„ start incall manager.
ringback accept non-empty string or it won't play
default: {media:'audio', auto: true, ringback: ''}
stop({busytone: ?string}) ๐Ÿ˜„ ๐Ÿ˜„ stop incall manager
busytone accept non-empty string or it won't play
default: {busytone: ''}
turnScreenOn() ๐Ÿ˜„ ๐Ÿ˜ก force turn screen on
turnScreenOff() ๐Ÿ˜„ ๐Ÿ˜ก force turn screen off
setKeepScreenOn(enable: ?boolean) ๐Ÿ˜„ ๐Ÿ˜„ set KeepScreenOn flag = true or false
default: false
setSpeakerphoneOn(enable: ?boolean) ๐Ÿ˜„ ๐Ÿ˜ก toggle speaker ON/OFF once. but not force
default: false
setForceSpeakerphoneOn(flag: ?boolean) ๐Ÿ˜„ ๐Ÿ˜„ true -> force speaker on
false -> force speaker off
null -> use default behavior according to media type
default: null
setMicrophoneMute(enable: ?boolean) ๐Ÿ˜„ ๐Ÿ˜ก mute/unmute micophone
default: false
p.s. if you use webrtc, you can just use track.enabled = false to mute
async checkRecordPermission() ๐Ÿ˜„ ๐Ÿ˜„ check record permission without promt. return Promise. see about permission section above
async requestRecordPermission() ๐Ÿ˜„ ๐Ÿ˜„ request record permission to user. return Promise. see about permission section above
async getAudioUriJS() ๐Ÿ˜„ ๐Ÿ˜„ get audio Uri path. this would be useful when you want to pass Uri into another module.

Events

Event android ios description
'Proximity' ๐Ÿ˜„ ๐Ÿ˜„ proximity sensor detected changes.
data: {'isNear': boolean}
'WiredHeadset' ๐Ÿ˜„ ๐Ÿ˜„ fire when wired headset plug/unplug
data: {'isPlugged': boolean, 'hasMic': boolean, 'deviceName': string }
'NoisyAudio' ๐Ÿ˜„ ๐Ÿ˜ก see andriod doc.
data: null
'MediaButton' ๐Ÿ˜„ ๐Ÿ˜ก when external device controler pressed button. see android doc
data: {'eventText': string, 'eventCode': number }
'onAudioFocusChange' ๐Ÿ˜„ ๐Ÿ˜ก see andriod doc
data: {'eventText': string, 'eventCode': number }

NOTE: platform OS always has the final decision, so some toggle api may not work in some case be care when customize your own behavior

LICENSE:

ISC License ( functionality equivalent to MIT License )

Contributing:

I'm not expert neither on ios nor android, any suggestions, pull request, corrections are really appreciated and welcome.

react-native-incall-manager's People

Contributors

ianlin avatar oney avatar sagivo avatar zxcpoiu avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.