Background Handling

While a user has joined a 100ms Room they can put the app in Background Mode & usually expect a certain subset of app functionality continues to work.

Background Mode implies that the application is not currently visible to the user, not responding to user input, and running in the Background.

Background state in React Native apps is represented by AppState.currentState === 'background' as described here.

Android & iOS have different mechanisms of handling app behaviour which includes limiting access to Camera & Microphone, time allowed to keep running before getting completely stopped, Aggressive Battery Optimisations on Android OEMs, etc.

There are 2 prominent behaviours that are mainly affected when apps transition to Background State - Publishing Audio/Video, and Playing incoming Audio/Video.

Let's breakdown how your apps can implement efficient handling of Background states on iOS & Android Platforms.

iOS Background Handling

When your app goes into the background, by default it can no longer access camera or microphone and publish it to other peers in the room. Also, you cannot hear audio of other participants in the call if your app is in the background without enabling Background Modes.

This is the default iOS platform behaviour whereby it limits access to Microphone & Camera for capturing Audio & Video. By default, iOS also stops playing audio of the Room when your app is in Background.

By Enabling Background Modes you can ensure that your iOS app has access to Microphone & can play incoming Audio from the Room.

Following steps show how to add Background Modes in iOS:

Open project in Xcode

Open project in Xcode by right clicking on ios folder in project and select Open in Xcode as shown in image below.

OpenXcode

Add Capability

Click on your Main App Project in Xcode Navigator then select TARGETS and click on Signing & Capabilities and add Capability. In the Example below, the Main App Target is RNHMSExample

addCapability

Background Mode

Search Background Mode and add it to Project by clicking on it.

backgroundMode

Enable Background Mode

Enable the checkbox under Background Modes named Audio, AirPlay, and Picture in Picture.

backgroundProcessing

Let's look at different scenarios on iOS with & without Enabling Background Modes.

Without Background Modes Enabled (Default iOS Behaviour)

The table lists down iOS app behaviours when the app transitions to background when a 100ms Room is ongoing without enabling background processing.

The "Scenario" on the left of the Table below implies the activity which is ongoing in the App when user has joined a 100ms Room.

The "Behaviours" on the right of the Table shows what happens when the App transitions to Background.

ScenarioBehaviours
Mic is UnmutedMic will get Muted
Camera is unmutedCamera will get Muted
Remote Peers are publishing audioIncoming Audio from Room Stops Playing

The table lists down iOS app behaviours when the app transitions to background when a 100ms Room is ongoing with Background Modes Enabled.

The "Scenario" on the left of the Table below implies the activity which is ongoing in the App when user has joined a 100ms Room.

The "Behaviours" on the right of the Table shows what happens when the App transitions to Background.

ScenarioBehaviours
Mic is unmutedMic will remain Unmuted and the user will able to publish audio without any restriction
Camera is unmutedCamera will get Muted
Remote Peers are publishing audioIncoming Audio from Room Continues to Play

Android Background Handling

On Android devices, by default Capturing Video & Audio from Camera & Microphone is allowed for sometime - usually 60 seconds. This time limit depends on different Android OEMs, Battery Optimisations Mode (Aggressive/Doze), etc. This leads to inconsistent behaviours of your apps in Background Mode on different Android devices.

As per your use-case, apps can choose to implement an Android Foreground Service to ensure consistent behaviour. With a Foreground Service, you can continuously access Microphone & Camera & publish the captured Audio & Video to other peers in the Room.

Foreground Services show a status bar notification, so that users are actively aware that your app is performing a task and is consuming system resources.

Note: Playing Audio continuously while app is in Background is allowed by default on Android devices.

Without Android Foreground Service (Default Android Behaviour)

The table below lists down Android app behaviours when the app transitions to background when a 100ms Room is ongoing without using any Android Foreground Service.

The "Scenario" on the left of the Table below implies the activity which is ongoing in the App when user has joined a 100ms Room.

The "Behaviours" on the right of the Table shows what happens when the App transitions to Background.

ScenarioBehaviours
Mic is unmutedMic will remain Unmuted and the user will able to publish audio for a limited period (time depending on OEMs)
Camera is UnmutedCamera will remain Unmuted and the user will able to publish video for a limited period (time depending on OS)
Remote Peers are publishing audioAble to play incoming audio from the Room

With Android Foreground Service

When your app implements a Foreground Service it continues access to capturing Audio & Video even when the app is in Background Mode.

ScenarioBehaviours
Mic is unmutedMic will remain unmuted and the user will able to publish audio without any restriction
Camera is unmutedCamera will remain unmuted and the user will able to publish video without any restriction
Remote Peers are publishing audioAble to play incoming audio from the Room

For implementing a Foreground Service, we recommend using the @voximplant/react-native-foreground-service package which allows the app to run in the background with a Persistent Status Bar Notification.

Below are the steps to implement Android Foreground Service using @voximplant/react-native-foreground-service in your React Native App

Install the package

npm i git+https://github.com/ygit/react-native-foreground-service

Update AndroidManifest.xml

  1. Add the FOREGROUND_SERVICE permission to the application's AndroidManifest.xml:
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
  1. Add VIForegroundService as a service to the application's AndroidManifest.xml:
<application> ... <activity> ... </activity> // Set Service Type to capture Audio or Video as per your use-case. In most cases, only `microphone` access would be required. Then do not pass the `camera`. If stopWithTask set to true then it will stop the notification if app is force killed.
<service android:name="com.voximplant.foregroundservice.VIForegroundService" android:foregroundServiceType="camera|microphone" android:stopWithTask="true" />
</application>
  1. If you have targetSdkVersion Android API >= 31 then perform the following step:

    Add android:exported="true" to the application's AndroidManifest.xml activity section

<activity android:name=".MainActivity" android:label="@string/app_name" android:configChanges="keyboard|keyboardHidden|orientation|screenSize" android:windowSoftInputMode="adjustResize" android:exported="true"> <===== Add this line

Usage of the package

  1. Import the module
import VIForegroundService from '@voximplant/react-native-foreground-service';
  1. Create Notification Channel
const androidForegroundServiceChannelConfig = { id: 'MyAppChannelID', name: 'My App Channel name', enableVibration: true, importance: 5, }; VIForegroundService.getInstance().createNotificationChannel( androidForegroundServiceChannelConfig ).then((r: any) => console.log('Created Android Foreground Service channel', r));
  1. Start Foreground Service
const startAndroidForegroundService = async () => { const notificationConfig = { channelId: 'MyAppChannelID', id: 1000, title: 'Foreground Service', // modify your notification title here! text: 'Starting Android Foreground Service now', // modify your notification text here! icon: '../assets/my-app-logo.png', // add your app's icon here priority: 2, }; try { VIForegroundService.getInstance().startService(notificationConfig); } catch (e) { console.error(e); } };
  1. Stop Foreground Service When the user leaves the Room or Room is ended, always stop the Foreground Service by calling the stopService method.
// a sample callback function invoked when user leaves the Room const handleMeetingLeave = useCallback(() => {
VIForegroundService.getInstance().stopService().then((result: any) => { // stop the Foreground Service
console.log('Stopped Android Foreground service: ', result); navigation.navigate('MyAppHomeScreen'); // navigate to app's Home Screen or any other appropriate screen }); }, []);

That's it

You have successfully implemented Android Foreground Service in your React Native App.

You can refer the sample implementation in 100ms Example app here.

Here's a sample screenshot of the Foreground Service Notification on Android.

Android Foreground Service Notification


Have a suggestion? Recommend changes ->

Was this helpful?

1234