react-native-webrtc / react-native-callkeep

iOS CallKit framework and Android ConnectionService for React Native
ISC License
922 stars 444 forks source link

[Android] backToForeground doesn't work when app is locked. #667

Open RamsayRomero opened 1 year ago

RamsayRomero commented 1 year ago

Bug report

Description

Calling backToForeground does not open the app when app is killed and locked. Calling backToForeground on all other states works as expected.

Steps to Reproduce

Force quit your app, lock your device, then wake your app with a notification by calling displayIncomingCall and backToForeground from a headless js task. This will show the incoming call screen, but will not cause your app to start.

Versions

- Callkeep: 4.3.6
- React Native: 0.68.2
- iOS:
- Android: 11
- Phone model: G91S

Logs

02-17 07:23:20.971 24731 24769 D RNCallKeep: [RNCallKeepModule] getInstance : ok
02-17 07:23:20.971 24731 24769 D RNCallKeep: [RNCallKeepModule] constructor
02-17 07:23:20.973 24731 24731 D RNCallKeep: [VoiceConnectionService] startObserving, event count: 0
02-17 07:23:20.974 24731 24769 D RNCallKeep: [RNCallKeepModule] updating react context
02-17 07:23:23.900 24731 24806 D RNCallKeep: [RNCallKeepModule] setup : { NativeMap: {"alertTitle":"Permissions required","alertDescription":"This application needs to access your phone account","cancelButton":"Cancel","okButton":"Ok","foregroundService":{"channelId":"com.autoid.mobile","channelName":"AutoID Mobile"}} }
02-17 07:23:23.900 24731 24806 D RNCallKeep: [VoiceConnectionService] setAvailable: false
02-17 07:23:23.900 24731 24806 D RNCallKeep: [VoiceConnectionService] setInitialized: true
02-17 07:23:23.900 24731 24806 D RNCallKeep: [RNCallKeepModule] setSettings : { NativeMap: {"alertTitle":"Permissions required","alertDescription":"This application needs to access your phone account","cancelButton":"Cancel","okButton":"Ok","foregroundService":{"channelId":"com.autoid.mobile","channelName":"AutoID Mobile"}} }
02-17 07:23:23.901 24731 24806 D RNCallKeep: [RNCallKeepModule] API Version supports self managed, but it is not enabled in setup
02-17 07:23:23.901 24731 24806 D RNCallKeep: [RNCallKeepModule] setSettings : { NativeMap: {"alertTitle":"Permissions required","alertDescription":"This application needs to access your phone account","cancelButton":"Cancel","okButton":"Ok","foregroundService":{"channelId":"com.autoid.mobile","channelName":"AutoID Mobile"}} }
02-17 07:23:23.902 24731 24806 D RNCallKeep: [RNCallKeepModule] registerPhoneAccount
02-17 07:23:23.908 24731 24806 D RNCallKeep: [RNCallKeepModule] registerEvents
02-17 07:23:23.908 24731 24806 D RNCallKeep: [RNCallKeepModule] startObserving, event count: 0
02-17 07:23:23.908 24731 24806 D RNCallKeep: [RNCallKeepModule] startObserving, event count: 0
02-17 07:23:23.908 24731 24806 D RNCallKeep: [VoiceConnectionService] setAvailable: true
02-17 07:23:23.908 24731 24806 D RNCallKeep: [VoiceConnectionService] setInitialized: true
02-17 07:23:23.909 24731 24806 W RNCallKeep: [RNCallKeepModule] checkPhoneAccountPermission error Activity doesn't exist
02-17 07:23:23.909 24731 24806 D RNCallKeep: [VoiceConnectionService] setCanMakeMultipleCalls: false
02-17 07:23:23.937 24731 24806 D RNCallKeep: [RNCallKeepModule] setSettings : { NativeMap: {"alertTitle":"Permissions required","alertDescription":"This application needs to access your phone account","cancelButton":"Cancel","okButton":"Ok","foregroundService":{"channelId":"com.autoid.mobile","channelName":"AutoID Mobile"}} }
02-17 07:23:23.938 24731 24806 D RNCallKeep: [RNCallKeepModule] registerPhoneAccount
02-17 07:23:23.943 24731 24806 D RNCallKeep: [RNCallKeepModule] registerEvents
02-17 07:23:23.943 24731 24806 D RNCallKeep: [RNCallKeepModule] startObserving, event count: 0
02-17 07:23:23.944 24731 24806 D RNCallKeep: [VoiceConnectionService] setAvailable: true
02-17 07:23:23.944 24731 24806 D RNCallKeep: [VoiceConnectionService] setInitialized: true
02-17 07:23:23.947 24731 24806 D RNCallKeep: [RNCallKeepModule] displayIncomingCall, uuid: 99b84aae-3a38-4e70-a3d7-c734d834f4a4, number: 1239, callerName: Ramsay Zoiper, hasVideo: true
02-17 07:23:23.963 24731 24731 D RNCallKeep: [VoiceConnectionService] Constructor
02-17 07:23:23.965 24731 24806 D RNCallKeep: [RNCallKeepModule] backToForeground, app isOpened ?false
02-17 07:23:23.982 24731 24731 D RNCallKeep: [VoiceConnectionService] onCreateIncomingConnection, name:Ramsay Zoiper, numbertel:1239, isForeground: true, isReachable:false, timeout: null
02-17 07:23:23.982 24731 24731 D RNCallKeep: [VoiceConnectionService] createConnection, callerNumber:tel:1239
02-17 07:23:23.987 24731 24731 D RNCallKeep: [VoiceConnectionService] PhoneAccount is not SELF_MANAGED, so connection won't be either
02-17 07:23:23.988 24731 24731 D RNCallKeep: [VoiceConnection] onStateChanged called, state : 0
02-17 07:23:23.988 24731 24731 D RNCallKeep: [VoiceConnection] onStateChanged called, state : 2
02-17 07:23:23.988 24731 24731 D RNCallKeep: [VoiceConnection] onStateChanged called, state : 1
02-17 07:23:23.988 24731 24731 D RNCallKeep: [VoiceConnectionService] startForegroundService
02-17 07:23:23.990 24731 24731 D RNCallKeep: [VoiceConnectionService] Starting foreground service
02-17 07:23:24.816 24731 24731 D RNCallKeep: [VoiceConnection] onCallAudioStateChanged muted :false
02-17 07:23:24.845 24731 24731 D RNCallKeep: [RNCallKeepModule][onReceive] ACTION_DID_CHANGE_AUDIO_ROUTE
02-17 07:23:24.845 24731 24731 V RNCallKeep: [RNCallKeepModule] sendEventToJS, eventName: RNCallKeepDidChangeAudioRoute, bound: true, hasListeners: true args : { NativeMap: {"output":"EARPIECE","callUUID":"99b84aae-3a38-4e70-a3d7-c734d834f4a4","handle":"1239"} }
02-17 07:23:30.850 24731 24731 D RNCallKeep: [VoiceConnection] onReject() executed
02-17 07:23:30.850 24731 24731 D RNCallKeep: [VoiceConnection] onReject executed, rejectReason: 0, replyMessage: null, rejected:false
02-17 07:23:30.851 24731 24731 D RNCallKeep: [VoiceConnection] onStateChanged called, state : 6
02-17 07:23:30.852 24731 24731 D RNCallKeep: [VoiceConnection] onReject executed
02-17 07:23:30.852 24731 24731 D RNCallKeep: [VoiceConnectionService] deinitConnection:99b84aae-3a38-4e70-a3d7-c734d834f4a4
02-17 07:23:30.852 24731 24731 D RNCallKeep: [VoiceConnectionService] stopForegroundService
02-17 07:23:30.858 24731 24731 D RNCallKeep: [RNCallKeepModule][onReceive] ACTION_END_CALL
02-17 07:23:30.859 24731 24731 V RNCallKeep: [RNCallKeepModule] sendEventToJS, eventName: RNCallKeepPerformEndCallAction, bound: true, hasListeners: true args : { NativeMap: {"callUUID":"99b84aae-3a38-4e70-a3d7-c734d834f4a4"} }

Note that the logs are the same as when I test with the app in a killed state but with my device unlocked. If this is the correct behavior, is there any way I can wake my app in the background on Android when a notification is received, the same way iOS VoIP notifications wake up the app in the background?

sunny0092 commented 1 year ago

I'm having the same problem, still no solution

RamsayRomero commented 1 year ago

@Sang-Nguyen-Sunny I was able to get it to work by following this example but now I have the same issue that they're asking about which is that the app will always bypass the lock screen if the phone is unlocked and in the background. The post has a solution but I don't know how to split my app into multiple activities in React Native so for now this will do. Also note that the example sometimes would not work for me so I added additional code to get it to work.

In my AndroidManifest.xml I added this permission: <uses-permission android:name="android.permission.DISABLE_KEYGUARD"/>

and to my ".MainActivity" activity I appended the following attributes: android:showOnLockScreen="true" android:showWhenLocked="true" android:turnScreenOn="true"

and I added additional code to the example to request keyguard dismissal, so I ended up with this:

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
      setShowWhenLocked(true);
      setTurnScreenOn(true);
      KeyguardManager keyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
      keyguardManager.requestDismissKeyguard(this, null);
    } getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
      | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
      | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);

and don't forget to import:

import android.view.WindowManager;
import android.app.KeyguardManager;
import android.content.Context;

Not an Android expert so I don't know how much of this code is actually needed but it's working for me. Sometimes the full screen incoming call ui shows up before the app comes to the foreground but the app still actually runs behind it, just like on iOS after receiving a VoIP notification, which is all I need.

wilmxre commented 1 year ago

adding android:showOnLockScreen="true" android:showWhenLocked="true" android:turnScreenOn="true" helped me to wake up app from killed locked state, thanks