我是移动应用程序开发的新手,我正在学习.NET毛伊岛。我正在创建的应用程序需要侦听加速度计事件,如果事件符合某些条件,则需要向web服务发送通知。我正在挣扎的地方是如何让应用程序在后台运行,即没有UI可见,不睡觉,因为我希望用户完全关闭UI。所以我认为这个应用程序需要作为某种服务运行,在需要的时候可以选择显示UI --这是怎么做到的呢?
发布于 2022-10-17 18:15:03
我知道这是一段时间,但会为未来的用户发布一个答案!
首先,我们需要了解后台服务取决于我们使用哪个平台。(谢谢杰森)和我将重点放在安卓,基于Xamarin文档 (感谢Eli),适应毛伊岛。
由于我们使用的是ANDROID,所以我们将在MauiProgram上添加以下内容:
#if ANDROID
builder.Services.AddTransient<IServiceTest, DemoServices>();
#endif
我们为DI创建了接口,为我们提供了启动和停止前台服务的方法
public interface IServiceTest
{
void Start();
void Stop();
}
然后,在平台代码之前,我们需要在AndroidManifest.xml上添加Android权限。
<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文档上,它们还显示了notification的不同属性。
[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();
}
//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的信息,那就太棒了!
https://stackoverflow.com/questions/71259615
复制相似问题