如何在Xamarin.Forms中创建一个在某个时间段工作的服务?

如何在Xamarin.Forms中创建一个在某个时间段工作的服务?,xamarin.forms,xamarin.android,Xamarin.forms,Xamarin.android,我正在构建一个应用程序,当应用程序第一次运行时,大约1小时或更长时间后,它会自动连接到服务器获取数据以进行prepair显示,即使用户关闭应用程序。首先,当用户关闭应用程序时,后台服务器不能与打开应用程序一样运行,它将被安卓系统关闭 如果应用程序在后台运行,Android应用程序将不再能够在Android 8.0(API级别26)或更高版本的后台自由运行。当应用程序移动到后台时,Android将授予应用程序一定的时间来启动和使用服务。一旦该时间过去,应用程序将无法再启动任何服务,任何已启动的服务

我正在构建一个应用程序,当应用程序第一次运行时,大约1小时或更长时间后,它会自动连接到服务器获取数据以进行prepair显示,即使用户关闭应用程序。首先,当用户关闭应用程序时,后台服务器不能与打开应用程序一样运行,它将被安卓系统关闭

如果应用程序在后台运行,Android应用程序将不再能够在Android 8.0(API级别26)或更高版本的后台自由运行。当应用程序移动到后台时,Android将授予应用程序一定的时间来启动和使用服务。一旦该时间过去,应用程序将无法再启动任何服务,任何已启动的服务将被终止。此时,应用程序无法执行任何工作

因此,根据您的需要,在前台启动服务是一个不错的选择(但用户无法关闭此应用程序)–当应用程序必须在后台执行某些任务,并且用户可能需要定期与该任务交互时,前台服务非常有用。前台服务将显示一个持久性通知,以便用户知道应用程序正在运行后台任务,并提供一种监视任务或与任务交互的方法

这是我的密码

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());
        };
    }
[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);
    }
}
}
然后实现
DependentService
以启动前台服务

DependentService.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());
        };
    }
[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);
    }
}
}
[assembly:Xamarin.Forms.Dependency(typeof(DependentService))]
名称空间TabGuesture.Droid
{
[服务]
公共类DependentService:服务,iSeries服务
{
公开作废开始()
{
var intent=新的intent(Android.App.Application.Context,
类型(从属服务);
if(Android.OS.Build.VERSION.SdkInt>=Android.OS.BuildVersionCodes.O)
{
Android.App.Application.Context.StartForegroundService(intent);
}
其他的
{
Android.App.Application.Context.StartService(intent);
}
}
公共覆盖iBind OnBind(意图)
{
返回null;
}
public const int SERVICE_RUNNING_NOTIFICATION_ID=10000;
公共覆盖StartCommandResult OnStartCommand(意图,
StartCommandFlags标志,int startId)
{
//从共享代码或您的PCL中
CreateNotificationChannel();
字符串messageBody=“服务启动”;
var notification=new notification.Builder(这是“10111”)
.SetContentTitle(Resources.GetString(Resource.String.app_name))
.SetContentText(messageBody)
.SetSmallIcon(Resource.Drawable.main)
.正在进行(正确)
.Build();
StartForeground(服务运行通知ID,通知);
//你工作吗
返回StartCommandResult.Sticky;
}
void CreateNotificationChannel()
{
if(Build.VERSION.SdkInt
有一个运行屏幕截图。(为了快速获得结果,我将时间跨度设置为6秒)


你好,Leon,所以如果用户关闭应用程序,我们就无法做到这一点?我看到一些应用程序,比如新闻应用程序,当他们有新消息时,他们会给我发送通知,而我关闭了那个应用程序?你能解释一下他们是怎么做的吗?新闻应用是通过使用高优先级Firebase云消息(FCM)来实现的,通常,它不是本地通知,而是通过谷歌云消息发送的。有关于服务器后端服务的链接。是否有此问题的更新?如果回复有帮助,请尝试将其标记为答案,这将帮助其他有类似问题的人。如果用户未关闭应用程序,它将正常工作。