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.