First of all, when user close the app, the background servers cannot running the same as open the app, it will be closed by Android system.
If app running in the backend, Android application no longer have the ability to run freely in the background in Android 8.0 (API level 26) or above. 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.
So, based on your needs, Start the service in the foreground is a good choice(but user cannot close this application) – a foreground service is useful for when the app must perform some task in the background and the user may need to periodically interact with that task. The foreground service will display a persistent notification so that the user is aware that the app is running a background task and also provides a way to monitor or interact with the task.
There is my code.
MainPage.cs
public partial class MainPage : ContentPage
{
static bool isRunning = true;
public MainPage()
{
InitializeComponent();
// BindingContext = new CollectionViewModel();
if(isRunning){
//setting one hours to open the service.
Device.StartTimer(TimeSpan.FromHours(1), () =>
{
// Do something
DependencyService.Get<IService>().Start();
return false; // True = Repeat again, False = Stop the timer
});
isRunning = false;
}
bt1.Clicked += (o, e) =>
{
Navigation.PushAsync(new Page1());
};
}
I used dependenceservice to achieve to forground service
.
IService.cs create a interface for android to start service.
public interface IService
{
void Start();
}
Then achieved DependentService
to start a Foreground Service.
DependentService.cs
[assembly: Xamarin.Forms.Dependency(typeof(DependentService))]
namespace TabGuesture.Droid
{
[Service]
public class DependentService : Service, IService
{
public void Start()
{
var intent = new Intent(Android.App.Application.Context,
typeof(DependentService));
if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.O)
{
Android.App.Application.Context.StartForegroundService(intent);
}
else
{
Android.App.Application.Context.StartService(intent);
}
}
public override IBinder OnBind(Intent intent)
{
return null;
}
public const int SERVICE_RUNNING_NOTIFICATION_ID = 10000;
public override StartCommandResult OnStartCommand(Intent intent,
StartCommandFlags flags, int startId)
{
// From shared code or in your PCL
CreateNotificationChannel();
string messageBody = "service starting";
var notification = new Notification.Builder(this, "10111")
.SetContentTitle(Resources.GetString(Resource.String.app_name))
.SetContentText(messageBody)
.SetSmallIcon(Resource.Drawable.main)
.SetOngoing(true)
.Build();
StartForeground(SERVICE_RUNNING_NOTIFICATION_ID, notification);
//do you work
return StartCommandResult.Sticky;
}
void CreateNotificationChannel()
{
if (Build.VERSION.SdkInt < BuildVersionCodes.O)
{
// Notification channels are new in API 26 (and not a part of the
// support library). There is no need to create a notification
// channel on older versions of Android.
return;
}
var channelName = Resources.GetString(Resource.String.channel_name);
var channelDescription = GetString(Resource.String.channel_description);
var channel = new NotificationChannel("10111", channelName, NotificationImportance.Default)
{
Description = channelDescription
};
var notificationManager = (NotificationManager)GetSystemService(NotificationService);
notificationManager.CreateNotificationChannel(channel);
}
}
}
There is running screenshot.(For a quick result, i set the timesspan to 6 secound)
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…