7

I am trying to provide a native video calling experience with Twilio Video Call. Here is the scenario:

  1. Person AAA calls person BBB.
  2. Person BBB does not have the app open, in the background or foreground, app is in killed state, phone may even be locked.
  3. When a call from AAA arrives, the app is opened with a video ui with an answer button. Just like in WhatsApp, Google Duo, Skype...

We have FCM in place and are receiving a push notification. Trying to open the video call answer button the moment the call arrives, without clicking the notification, just like in Whatsapp, Google Duo... (in Android phones)

We tried to have a Service running in the background with a socket open in it. The socket would listen to incoming calls and open the VideoCallActivity when an incoming call event is emitted to the socket.

This was our best bet but no success so far. How would you achieve this functionality?

ousanmaz
  • 311
  • 3
  • 10

1 Answers1

20

So we had figured out this solution (when a notification arrives, bring the app to foreground) and I'm posting it even though it's been a while:

  1. The FCM notification (firebase cloud messaging notification) needs to only send "data" in the notification. So no Notification object in the JSON structure of the notification, only data. This way the notification is handled by your app's FirebaseMessagingService.java class. Please read the below in detail to understand how 2 FCM notification types are handled. https://firebase.google.com/docs/cloud-messaging/android/receive https://firebase.google.com/docs/cloud-messaging/concept-options#notifications_and_data_messages

  2. In the FirebaseMessagingService.java class, launch a VideoCall activity with an Intent. Don't forget to add this service to the Manifest.xml

             Intent intent = new Intent(this, VideoCallActivity.class);
             intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
             intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
             getApplicationContext().startActivity(intent);
    
  3. In the VideoCall activity, make sure you have the below code at the beginning of onCreate() :

     // These flags ensure that the activity can be launched when the screen is locked.
     Window window = getWindow();
     window.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
             | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
             | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
    
     // to wake up the screen
     PowerManager pm = (PowerManager) getApplicationContext().getSystemService(Context.POWER_SERVICE);
     PowerManager.WakeLock wakeLock = pm.newWakeLock((PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP), "TAG");
     wakeLock.acquire();
    
     // to release the screen lock
     KeyguardManager keyguardManager = (KeyguardManager) getApplicationContext().getSystemService(Context.KEYGUARD_SERVICE);
     KeyguardManager.KeyguardLock keyguardLock = keyguardManager.newKeyguardLock("TAG");
     keyguardLock.disableKeyguard();
    
  4. Add the VideoCallActivity to the Manifest.xml with the appropriate intent-filter:

    <!-- Video Call -->
    <activity
        android:name=".ui.activities.video_call.VideoCallActivity"
        android:launchMode="singleTop"
        android:screenOrientation="portrait"
        android:theme="@style/AppTheme.NoActionBar">
        <intent-filter>
            <!-- Note: these actions are notification actions -->
            <action android:name="VIDEO_CALLING" />
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    </activity>
    
    

Optional: To make the phone ring and vibrate:

// For Incoming Call
// 1. declare
private MediaPlayer incomingCallMediaPlayer;
// .2 in onCreate, if I'm the person that's calling, ring the phone 
incomingCallMediaPlayer = MediaPlayer.create(this, R.raw.incoming);
incomingCallMediaPlayer.setLooping(true);
incomingCallMediaPlayer.start();
// 3. when I pick up, stop the player
incomingCallMediaPlayer.stop();

// I play R.raw.incoming if I'm being called.
// I play R.raw.outgoing when I'm calling.
// I understand if I'm the one calling from the number of participants in the "room" (this is a video call terminology) and bypassing in a variable through the intent

// For Outgoing Call
// 1. declare
private MediaPlayer callingMediaPlayer;

// 2. in onCreate, if I'm being called, ring the phone
callingMediaPlayer = MediaPlayer.create(this, R.raw.outgoing);
callingMediaPlayer.setLooping(true);
callingMediaPlayer.start();

// 3. when another "participant" (this is a video call terminology) joins the "room" I stop playing the sound
callingMediaPlayer.stop();

// to Vibrate, add the code with the media players and stop vibrate with media players
//https://stackoverflow.com/questions/13950338/how-to-make-an-android-device-vibrate
Skaranjit
  • 764
  • 9
  • 26
ousanmaz
  • 311
  • 3
  • 10
  • Is using FCM push notification effective in real time? or is there any better option to do so, some time push notification wont reach the client immediately it may delay right? – Praneeth Nov 27 '18 at 11:00
  • @Praneeth Not that I know of but if anyone else has a better option than fcm push notification please share. Praneeth we tried having a socket open in the background for incoming video calls but didn't quite work. It complicated the process. However, during many internal tests and in the alpha group we didn't see any issues with delay. – ousanmaz Nov 27 '18 at 22:07
  • I have implemented twilio video calling in my app and the push is working fine in foreground but when it is in back ground I'm unable to open my activity, even I'm sending data message it is displayed in the notification tray – Praneeth Nov 29 '18 at 17:47
  • 1
    can you please explain how you are bringing the app to forground when app is closed or locked – Praneeth Nov 29 '18 at 17:54
  • When the notification arrives, the data in the notification is handled by FireBaseMessagingService.java class as described in step 2 and starts an intent to open VideoCallActivity class. The code in step 3. allows the app to unlock the come to the foreground. I am guessing you also have the FirebaseMessagingService in the Manifest. If you've done all these it should work. If you'd like I can take a look at your code. – ousanmaz Nov 30 '18 at 04:47
  • thank you for your time, Yes I have class which extends FireBaseMessagingService and Implements onMessageRecived call back method I need to send data message alone I think. – Praneeth Nov 30 '18 at 09:12
  • When my app is in background when I send a push notification, the push notification is shown in notification tray as normal push notification, my app is not coming to for ground. – Praneeth Nov 30 '18 at 09:40
  • Okay, since it is working when the app is in the foreground but not in the background, it makes me think the issue is with the notification. This tricked me for a while to understand the difference between 2 notifications. The following link will help you on Data and Notification notifications: https://firebase.google.com/docs/cloud-messaging/concept-options#notifications_and_data_messages – ousanmaz Nov 30 '18 at 18:27
  • How are you handling when the app enter into Doze mode in android – Praneeth Dec 03 '18 at 13:15
  • 2
    To be honest, I didn't. You just brought it to my attention and thank you for that. – ousanmaz Dec 03 '18 at 14:35
  • Ok I think I will figure it out, once I got any solution I will update here, can we able to make phone vibrate or ring a tone when we handle notification? – Praneeth Dec 03 '18 at 14:45
  • I added the code to ring and vibrate in my original answer. Let me know if clear or any problems you encounter. – ousanmaz Dec 03 '18 at 17:19
  • 1
    @Praneeth hi - did you ever figure this out? :) – Rob Grant Jul 07 '20 at 18:36
  • @ousanmaz for the second point, on which event, the code will be called.. onMessageReceived works only when the app is in foreground IMO – Lakshay Dulani Nov 26 '20 at 05:57
  • hi, i also looking for this. any one have the solution? need some one to save my day lol – Min Hong Tan Dec 11 '20 at 15:58