The first step of the call is a notification. We’re using OneSignal to send push notifications to the device, and there is a npm package for React Native (https://github.com/geektimecoil/react-native-onesignal) to manage that. Our goal was to build an app to make VoIP calls.
Users are used to receive the call even if the device is locked and the app process is not running. This is simple on iOS. You can use a very powerful system API called PushKit, which basically does all the work for you. In this case an open source library is saving us once again (https://github.com/ianlin/react-native-callkit)!
That’s great! But what about Android? Well.. Here comes the trouble! 😢
Receive push notifications when the app is not alive
The first step is writing a service which receives push notifications even if the app is not alive. For the sake of simplicity we’ll use WakefulBroadcastReceiver in this example, but we suggest using a JobScheduler to detect notifications in a better way.
The onReceive event will be triggered every time we receive a push from the GCM (remember to add the service to your AndroidManifest.xml). From here we’ll start a BackgroundService which basically just starts your React Native activity with an Intent.
Awesome! Now our React Native activity is up and running!
Now we need to show our activity over the lock screen and send the user choice (receive or decline the call) to the app.
The following steps are assuming that you are using some package to handle navigation properly inside your app. We used https://github.com/wix/react-native-navigation which is one of the most supported libs.
Based on this package, we need to extend the NavigationApplication class. This way, we get access to the lifecycle methods of our activities where we can set some flags and start our UnlockScreenActivity.
It’s really important to add the flag on the NavigationActivity, which is the activity generated by react-native-navigation that will be the container of our app. We need to put it over the lock screen, otherwise if you put it only on your “UnlockScreenActivity”, you’ll see the custom screen and after that the phone will turn the screen off again 😓
N.B. you need to set these flags before calling setContentView inside the onCreate method. Keep it in mind!
Last but not least, our UnlockScreenActivity
Great, now your Java code is ready!
We now need to connect your React Native app with a listener to the event emitted by your screen and we are ready to go:
That’s it! The magic is working! 🎩
- Starting from Android SDK 23, we have access to ConnectionService which is similar to what PushKit does on iOS. Probably you can get a better solution using it.
- The activities lifecycles in this article is quite generic. Pay attention where you add the flags on the window in order to be sure to obtain the desired result.
- We’ve followed this implementation because we didn’t want to duplicate business login and networking code between JS and Java, but maybe there is better way to handle this directly inside React Native 🙂