Как создать фоновую службу в .NET Maui
Я новичок в разработке мобильных приложений и изучаю .NET Maui. Приложение, которое я создаю, должно прослушивать события акселерометра и отправлять уведомление в веб-службу, если события соответствуют определенным критериям. Немного, с которым я борюсь, - это то, как запустить приложение в фоновом режиме, то есть без видимого пользовательского интерфейса, без перехода в спящий режим, поскольку я бы хотел, чтобы пользователь полностью закрыл пользовательский интерфейс. Поэтому я думаю, что приложение должно работать как своего рода служба с возможностью отображения пользовательского интерфейса при необходимости - как это можно сделать?
2 ответа
я знаю, что это было какое-то время, но опубликую ответ для будущих пользователей!
Во-первых, нам нужно понять, что фоновые службы зависят от того, какую платформу мы используем (спасибо, Джейсон). И я сосредоточусь на ANDROID, основанном на документации Xamarin (спасибо, Эли), адаптированной для Мауи.
Так как мы работаем с ANDROID , на MauiProgram добавим следующее:
/// Add dependecy injection to main page
builder.Services.AddSingleton<MainPage>();
#if ANDROID
builder.Services.AddTransient<IServiceTest, DemoServices>();
#endif
И мы создаем наш интерфейс для DI, который предоставляет нам методы для запуска и остановки службы переднего плана.
public interface IServiceTest
{
void Start();
void Stop();
}
Затем перед кодом платформы нам нужно добавить разрешения Android в AndroidManifest.xml :
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
Основное действие Android
public class MainActivity : MauiAppCompatActivity
{
//set an activity on main application to get the reference on the service
public static MainActivity ActivityCurrent { get; set; }
public MainActivity()
{
ActivityCurrent = this;
}
}
И, наконец, мы создаем нашу службу переднего плана Android. Проверьте комментарии ниже. Также в документах xamarin показаны различные свойства построителя уведомлений.
[Service]
public class DemoServices : Service, IServiceTest //we implement our service (IServiceTest) and use Android Native Service Class
{
public override IBinder OnBind(Intent intent)
{
throw new NotImplementedException();
}
[return: GeneratedEnum]//we catch the actions intents to know the state of the foreground service
public override StartCommandResult OnStartCommand(Intent intent, [GeneratedEnum] StartCommandFlags flags, int startId)
{
if (intent.Action == "START_SERVICE")
{
RegisterNotification();//Proceed to notify
}
else if (intent.Action == "STOP_SERVICE")
{
StopForeground(true);//Stop the service
StopSelfResult(startId);
}
return StartCommandResult.NotSticky;
}
//Start and Stop Intents, set the actions for the MainActivity to get the state of the foreground service
//Setting one action to start and one action to stop the foreground service
public void Start()
{
Intent startService = new Intent(MainActivity.ActivityCurrent, typeof(DemoServices));
startService.SetAction("START_SERVICE");
MainActivity.ActivityCurrent.StartService(startService);
}
public void Stop()
{
Intent stopIntent = new Intent(MainActivity.ActivityCurrent, this.Class);
stopIntent.SetAction("STOP_SERVICE");
MainActivity.ActivityCurrent.StartService(stopIntent);
}
private void RegisterNotification()
{
NotificationChannel channel = new NotificationChannel("ServiceChannel", "ServiceDemo", NotificationImportance.Max);
NotificationManager manager = (NotificationManager)MainActivity.ActivityCurrent.GetSystemService(Context.NotificationService);
manager.CreateNotificationChannel(channel);
Notification notification = new Notification.Builder(this, "ServiceChannel")
.SetContentTitle("Service Working")
.SetSmallIcon(Resource.Drawable.abc_ab_share_pack_mtrl_alpha)
.SetOngoing(true)
.Build();
StartForeground(100, notification);
}
}
Теперь у нас есть служба переднего плана, работающая на Android, которая показывает уведомление («Служба работает»). Каждый раз, когда он начинается. Я делаю службу переднего плана для показа сообщений, чтобы лучше видеть ее во время тестирования, в вашем случае предполагается закрытие приложения, если это то, что вы хотите, но функционирование это то же самое.
Итак, работая с нашей фоновой службой, остался только способ вызвать ее, поэтому на нашей главной странице (в качестве примера) я сделаю следующее:
MainPage.xaml
<VerticalStackLayout>
<Label
Text="Welcome to .NET Multi-platform App UI"
FontSize="18"
HorizontalOptions="Center" />
<Button
x:Name="CounterBtn"
Text="start Services"
Clicked="OnServiceStartClicked"
HorizontalOptions="Center" />
<Button Text="Stop Service" Clicked="Button_Clicked"></Button>
</VerticalStackLayout>
MainPage.xaml.cs
public partial class MainPage : ContentPage
{
IServiceTest Services;
public MainPage(IServiceTest Services_)
{
InitializeComponent();
ToggleAccelerometer();
Services = Services_;
}
//method to start manually foreground service
private void OnServiceStartClicked(object sender, EventArgs e)
{
Services.Start();
}
//method to stop manually foreground service
private void Button_Clicked(object sender, EventArgs e)
{
Services.Stop();
}
//method to work with accelerometer
public void ToggleAccelerometer()
{
if (Accelerometer.Default.IsSupported)
{
if (!Accelerometer.Default.IsMonitoring)
{
Accelerometer.Default.ReadingChanged += Accelerometer_ReadingChanged;
Accelerometer.Default.Start(SensorSpeed.UI);
}
else
{
Accelerometer.Default.Stop();
Accelerometer.Default.ReadingChanged -= Accelerometer_ReadingChanged;
}
}
}
//on accelerometer property change we call our service and it would send a message
private void Accelerometer_ReadingChanged(object sender, AccelerometerChangedEventArgs e)
{
Services.Start(); //this will never stop until we made some logic here
}
}
Это длинный ответ, и было бы здорово иметь больше официальной документации по этому поводу! Надеюсь, поможет! Если кто-нибудь может предоставить больше информации о IOS, Windows, MacCatalyst, было бы здорово!
Моя репутация слишком низкая, чтобы добавлять комментарии
Чтобы добавить к ответу Леандро, вы должны указать использование в правильной ОС платформы. В противном случае вы не сможете использовать IntelliSense для добавления использований.
Выберите ОС Android в раскрывающемся списке, показанном на этом изображении:Выбор раскрывающегося списка ОС Android.
Теперь вы можете использовать IntelliSense для добавления файлов using.
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;