0

I have created BroadcastReceiver where I detect when an incoming call is received on the device. My code is

[BroadcastReceiver()]
[IntentFilter(new[] { "android.intent.action.PHONE_STATE" })]
public class MyBroadcastReceiver : BroadcastReceiver
{
    public override void OnReceive(Context context, Intent intent)
    {
    //My implementation
    }
}

Problem is when the application is not running or killed forcefully, BroadcastReceiver class does not get called. Can anyone please help?

FreakyAli
  • 13,349
  • 3
  • 23
  • 63
u_1826
  • 57
  • 2
  • 14

2 Answers2

0

BroadcastReceiver will not work when the application is killed, you have to use service for that , you can use BroadcastReceiver inside a service to run it even when the app is not running.

Galib Imtiaz
  • 106
  • 2
  • 7
  • Thanks for the reply, Can you please share any example if you have? i am just the beginner to mobile development. – u_1826 Jan 19 '18 at 18:23
0

BroadcastReceiver does not work when application is not in background or killed

You could refer to: Android Broadcast Receiver not working when the app is killed, as CommonsWare said:

Once onReceive() returns, if you do not have an activity in the foreground and you do not have a running service, your process importance will drop to what the documentation refers to as a "cached process". Your process is eligible to be terminated at any point. Once your process is terminated, your BroadcastReceiver goes away. Hence, your code as written will be unreliable, as your process might be terminated within your 30-second window.

Solution:

So you could use a Service to implement your feature, here is my simple demo:

[Service]
[IntentFilter(new String[] { "com.xamarin.DemoService" })]
public class DemoService : Service
{
    private static DemoReceiver m_ScreenOffReceiver;

    public override IBinder OnBind(Intent intent)
    {
        return null;
    }

    public override void OnCreate()
    {
        registerScreenOffReceiver();
        base.OnCreate();
    }

    public override void OnDestroy()
    {
        UnregisterReceiver(m_ScreenOffReceiver);
        m_ScreenOffReceiver = null;
        base.OnDestroy();
    }

    //From this thread: https://stackoverflow.com/questions/20592366/the-process-of-the-service-is-killed-after-the-application-is-removed-from-the-a
    public override void OnTaskRemoved(Intent rootIntent)
    {
        Intent restartServiceIntent = new Intent(Application.Context, typeof(DemoService));
        restartServiceIntent.SetPackage(PackageName);

        PendingIntent restartServicePendingIntent = PendingIntent.GetService(Application.Context, 1, restartServiceIntent, PendingIntentFlags.OneShot);
        AlarmManager alarmService = (AlarmManager)Application.Context.GetSystemService(Context.AlarmService);
        alarmService.Set(AlarmType.ElapsedRealtime, SystemClock.ElapsedRealtime() + 1000, restartServicePendingIntent);
        base.OnTaskRemoved(rootIntent);
    }

    private void registerScreenOffReceiver()
    {
        m_ScreenOffReceiver = new DemoReceiver();
        IntentFilter filter = new IntentFilter("com.xamarin.example.TEST");
        RegisterReceiver(m_ScreenOffReceiver, filter);
    }
}

Update:

If you need the service run at a higher priority to avoid it be killed, you could try using Foreground Service. As SushiHangover said:

As a foreground service it has a higher priority so the OS will consider it last to be killed, it avoids the automatic dozing of your services to save battery in later APIs , etc... The "downside" is the user must be made aware that it is running, thus the requirement to be placed in the notification bar, personally I do not see that as a problem and wish it was a hard requirement for all services.

York Shen
  • 9,014
  • 1
  • 16
  • 40