Hello,
Welcome to our Microsoft Q&A platform!
Starting in Android 8.0 (API level 26), an Android application no longer have the ability to run freely in the background. When an application moves into the background, Android will grant the app a certain amount of time to start and use services. Once that time has elapsed, the app can no longer start any services and any services that were started will be terminated. At this point it is not possible for the app to perform any work.
To keep the service working even when the app is closed, try using a ForegroundService
instead. Here is the sample code:
[Service(Enabled = true)]
public class CustomService : Service
{
private Handler handler;
private Action runnable;
private bool isStarted;
private int DELAY_BETWEEN_LOG_MESSAGES = 5000;
private int NOTIFICATION_SERVICE_ID = 1001;
private int NOTIFICATION_AlARM_ID = 1002;
private string NOTIFICATION_CHANNEL_ID = "1003";
private string NOTIFICATION_CHANNEL_NAME = "MyChannel";
public override void OnCreate()
{
base.OnCreate();
handler = new Handler();
//here is what you want to do always
runnable = new Action(() =>
{
if (isStarted)
{
DispatchNotificationThatAlarmIsGenerated("I'm running");
//the function
handler.PostDelayed(runnable, DELAY_BETWEEN_LOG_MESSAGES);
}
});
}
public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
{
if (isStarted)
{
// service is already started
}
else
{
CreateNotificationChannel();
DispatchNotificationThatServiceIsRunning();
handler.PostDelayed(runnable, DELAY_BETWEEN_LOG_MESSAGES);
isStarted = true;
}
return StartCommandResult.Sticky;
}
private void DispatchNotificationThatServiceIsRunning()
{
var notificationManager = (NotificationManager)GetSystemService(NotificationService);
if (Build.VERSION.SdkInt > BuildVersionCodes.O)
{
var chan = new NotificationChannel(NOTIFICATION_CHANNEL_ID, GetString(Resource.String.abc_action_bar_home_description), NotificationImportance.Default);
chan.LightColor = Android.Graphics.Color.Green;
chan.LockscreenVisibility = NotificationVisibility.Private;
notificationManager.CreateNotificationChannel(chan);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID)
.SetAutoCancel(false)
.SetSmallIcon(Resource.Drawable.abc)
.SetContentTitle("Mobile")
.SetContentText("My service started");
StartForeground(NOTIFICATION_SERVICE_ID, builder.Build());
}
else
{
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID)
.SetDefaults((int)NotificationDefaults.All)
.SetSmallIcon(Resource.Drawable.abc)
.SetVibrate(new long[] { 100, 200, 300, 400, 500, 400, 300, 200, 400 })
.SetSound(null)
.SetPriority(NotificationCompat.PriorityDefault)
.SetAutoCancel(false)
.SetContentTitle("Mobile")
.SetContentText("My service started")
.SetOngoing(true);
StartForeground(NOTIFICATION_SERVICE_ID, builder.Build());
}
}
private void DispatchNotificationThatAlarmIsGenerated(string message)
{
var intent = new Intent(this, typeof(MainActivity));
intent.AddFlags(ActivityFlags.ClearTop);
var pendingIntent = PendingIntent.GetActivity(this, 0, intent, PendingIntentFlags.OneShot);
var notificationManager = (NotificationManager)GetSystemService(NotificationService);
if (Build.VERSION.SdkInt > BuildVersionCodes.O)
{
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, "default")
.SetContentTitle("Alarm")
.SetContentText(message)
.SetSmallIcon(Resource.Drawable.abc)
.SetAutoCancel(true);
var chan = new NotificationChannel(NOTIFICATION_CHANNEL_ID, GetString(Resource.String.abc_action_bar_home_description), NotificationImportance.Default);
chan.LightColor = Android.Graphics.Color.Green;
chan.LockscreenVisibility = NotificationVisibility.Private;
notificationManager.CreateNotificationChannel(chan);
notificationManager.Notify(NOTIFICATION_AlARM_ID, notificationBuilder.Build());
}
else
{
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID)
.SetDefaults((int)NotificationDefaults.All)
.SetSmallIcon(Resource.Drawable.abc)
.SetVibrate(new long[] { 100, 200, 300, 400, 500, 400, 300, 200, 400 })
.SetSound(null)
.SetPriority(NotificationCompat.PriorityDefault)
.SetAutoCancel(false)
.SetContentTitle("Mobile")
.SetContentText("My service started")
.SetOngoing(true);
notificationManager.Notify(NOTIFICATION_AlARM_ID, notificationBuilder.Build());
}
}
public override void OnTaskRemoved(Intent rootIntent)
{
//base.OnTaskRemoved(rootIntent);
}
public override IBinder OnBind(Intent intent)
{
// Return null because this is a pure started service. A hybrid service would return a binder that would
// allow access to the GetFormattedStamp() method.
return null;
}
public override void OnDestroy()
{
// Stop the handler.
handler.RemoveCallbacks(runnable);
// Remove the notification from the status bar.
var notificationManager = (NotificationManager)GetSystemService(NotificationService);
notificationManager.Cancel(NOTIFICATION_SERVICE_ID);
isStarted = false;
base.OnDestroy();
}
private void CreateNotificationChannel()
{
//Notification Channel
NotificationChannel notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, NOTIFICATION_CHANNEL_NAME, NotificationImportance.Max);
notificationChannel.EnableLights(true);
notificationChannel.EnableVibration(true);
notificationChannel.SetVibrationPattern(new long[] { 100, 200, 300, 400, 500, 400, 300, 200, 400 });
NotificationManager notificationManager = (NotificationManager)this.GetSystemService(Context.NotificationService);
notificationManager.CreateNotificationChannel(notificationChannel);
}
}
Check the doc: https://learn.microsoft.com/en-us/xamarin/android/app-fundamentals/services/foreground-services
Best Regards,
Jarvan Zhang
If the response is helpful, please click "Accept Answer" and upvote it.
Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.