'Call from foreground service stops working when screen is off

I have the following code that makes a phone call:

public static void CallPhoneNumber(this Context context, string phoneNumber)
{
    var uri = Android.Net.Uri.Parse("tel:" + phoneNumber);
    var callIntent = new Intent(Intent.ActionCall, uri);
    callIntent.AddFlags(ActivityFlags.NewTask);
    callIntent.AddFlags(ActivityFlags.FromBackground);
    context.StartActivity(callIntent);
}

I make a phone call inside a running foreground service. Basically the service detects conditions (in my case GPS location) and makes a phone call. It worked just fine with my Pixel 2XL and Android 9. But after upgrade to Android 10 I faced to a new problem.

First of all, I was forced to add a new permission FOREGROUND_SERVICE. Added, the foreground service works as expected and makes phone calls - but only when phone is "active", I mean it is not in a "sleep" mode when the screen is turned off.

If the screen is off - the service works, I can track the activity, but it doesn't make a phone call.

The adb logcat shows this warning (first line is Info, the second is Warning):

02-04 20:48:00.923  1315  7951 I ActivityTaskManager: START u0 {act=android.intent.action.CALL dat=tel:xxxxxxxxxxxx flg=0x10000004 cmp=com.android.server.telecom/.components.UserCallActivity} from uid 10174
02-04 20:48:00.924  1315  7951 W ActivityTaskManager: Background activity start [callingPackage: MyApp; callingUid: 10175; isCallingUidForeground: false; isCallingUidPersistentSystemProcess: false; realCallingUid: 10174; isRealCallingUidForeground: false; isRealCallingUidPersistentSystemProcess: false; originatingPendingIntent: null; isBgStartWhitelisted: false; intent: Intent { act=android.intent.action.CALL dat=tel:xxxxxxxxxxxx flg=0x10000004 cmp=com.android.server.telecom/.components.UserCallActivity }; callerApp: ProcessRecord{43f3a72 13957:MyApp/u0a174}]


Solution 1:[1]

I think you should take a look at "partial wakelock" to prevent the "sleep mode" of the phone.

https://developer.android.com/training/scheduling/wakelock

in your MainActivity.cs create a WakeLock object and under your OnCreate function configure your wakelock :

private PowerManager.WakeLock wl = null;

protected override void OnCreate(Bundle savedInstanceState)
{
    // ... Your own code here
    PowerManager pmanager = (PowerManager)this.GetSystemService("power");
    wl = pmanager.NewWakeLock(WakeLockFlags.Partial, "myapp_wakelock");
    wl.SetReferenceCounted(false);
    wl.Acquire();
 }

Don't forget to add a permission in your AndroidManifest.xml:

<uses-permission android:name="android.permission.WAKE_LOCK" />

This solution can work but you're need to be carreful because for some manufacturer, if your app use to many ressources the foreground service responsible of the state "always alive" of the CPU can be killed. In some cases, they add a "battery saver" option mode and you need to disable it directly in settings to run your app without issues.

Hope this can help

Solution 2:[2]

Use TelecomManager. Something like this:

    Uri uri = Uri.fromParts("tel", phoneNumber, null);
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) == PackageManager.PERMISSION_GRANTED) {

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            TelecomManager telecomManager = (TelecomManager) getInstance().getSystemService(Context.TELECOM_SERVICE);
            telecomManager.placeCall(uri, new Bundle());
        }
        else
        {
            Intent callIntent = new Intent(Intent.ACTION_CALL, uri);
            callIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            startActivity(callIntent);
        }
    }

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 blackhorse.reddog