首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在.NET Maui中创建后台服务

如何在.NET Maui中创建后台服务
EN

Stack Overflow用户
提问于 2022-02-25 00:04:08
回答 1查看 5.3K关注 0票数 14

我是移动应用程序开发的新手,我正在学习.NET毛伊岛。我正在创建的应用程序需要侦听加速度计事件,如果事件符合某些条件,则需要向web服务发送通知。我正在挣扎的地方是如何让应用程序在后台运行,即没有UI可见,不睡觉,因为我希望用户完全关闭UI。所以我认为这个应用程序需要作为某种服务运行,在需要的时候可以选择显示UI --这是怎么做到的呢?

EN

回答 1

Stack Overflow用户

发布于 2022-10-17 18:15:03

我知道这是一段时间,但会为未来的用户发布一个答案!

首先,我们需要了解后台服务取决于我们使用哪个平台。(谢谢杰森)和我将重点放在安卓,基于Xamarin文档 (感谢Eli),适应毛伊岛。

由于我们使用的是ANDROID,所以我们将在MauiProgram上添加以下内容:

代码语言:javascript
运行
复制
#if ANDROID
    builder.Services.AddTransient<IServiceTest, DemoServices>();
#endif

我们为DI创建了接口,为我们提供了启动和停止前台服务的方法

代码语言:javascript
运行
复制
public interface IServiceTest
{
    void Start();
    void Stop();
}

然后,在平台代码之前,我们需要在AndroidManifest.xml上添加Android权限。

代码语言:javascript
运行
复制
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />

Android主要活动

代码语言:javascript
运行
复制
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文档上,它们还显示了notification的不同属性。

代码语言:javascript
运行
复制
[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

代码语言:javascript
运行
复制
<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

代码语言:javascript
运行
复制
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();
    }
    //methos 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的信息,那就太棒了!

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71259615

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档