Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
427 views
in Technique[技术] by (71.8m points)

xamarin.android - How to create service doing work at period time in Xamarin.Forms?

I'm building application that is when the application run first time, after that about 1 hours or more, it is automatic connect to server get data for prepair display eventhough the user close the app

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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)

enter image description here


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...