【问题标题】:Xamarin Forms Android & iOS Background FetchXamarin Forms Android & iOS 背景提取
【发布时间】:2020-02-03 12:03:26
【问题描述】:

大家好, 我想在 Xamarin 表单中向我的 rest api 请求,下载数据并比较另一个,如果它适合在应用程序关闭时在后台存在本地通知的条件。 我怎样才能以两分钟的间隔在后台执行此操作? 我正在研究几天,但我找不到任何东西。 有人帮我吗? 谢谢:)

【问题讨论】:

    标签: rest xamarin.forms xamarin.android xamarin.ios background-service


    【解决方案1】:

    您的意思是您希望它在您的应用关闭时工作吗?如果是的话,你可以考虑使用Foreground Services

    这里有一个简单的 Android 示例,您可以参考,您可以根据需要更改runnable

    1.创建服务MyService.cs

    [Service(Enabled = true)]
    public class MyService : Service
    {
        private Handler handler;
        private Action runnable;
        private bool isStarted;
        private int DELAY_BETWEEN_LOG_MESSAGES = 5000;
        private int NOTIFICATION_SERVICE_ID = 1001;
        private int NOTIFICATION_AlARM_ID = 1002;
        private string NOTIFICATION_CHANNEL_ID = "1003";
        private string NOTIFICATION_CHANNEL_NAME = "MyChannel";
        public override void OnCreate()
        {
            base.OnCreate();
    
            handler = new Handler();
    
            //here is what you want to do always, i just want to push a notification every 5 seconds here
            runnable = new Action(() =>
            {
               if (isStarted)
                {
                    DispatchNotificationThatAlarmIsGenerated("I'm running");
                    handler.PostDelayed(runnable, DELAY_BETWEEN_LOG_MESSAGES);
                }
            });
        }
    
        public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
        {
            if (isStarted)
            {
                // service is already started
            }
            else
            {
                CreateNotificationChannel();
                DispatchNotificationThatServiceIsRunning();
    
                handler.PostDelayed(runnable, DELAY_BETWEEN_LOG_MESSAGES);
                isStarted = true;
            }
            return StartCommandResult.Sticky;
        }
    
        public override void OnTaskRemoved(Intent rootIntent)
        {
            //base.OnTaskRemoved(rootIntent);
        }
    
        public override IBinder OnBind(Intent intent)
        {
            // Return null because this is a pure started service. A hybrid service would return a binder that would
            // allow access to the GetFormattedStamp() method.
            return null;
        }
    
        public override void OnDestroy()
        {
            // Stop the handler.
            handler.RemoveCallbacks(runnable);
    
            // Remove the notification from the status bar.
            var notificationManager = (NotificationManager)GetSystemService(NotificationService);
            notificationManager.Cancel(NOTIFICATION_SERVICE_ID);
    
            isStarted = false;
            base.OnDestroy();
        }
    
        private void CreateNotificationChannel()
        {
            //Notification Channel
            NotificationChannel notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, NOTIFICATION_CHANNEL_NAME, NotificationImportance.Max);
            notificationChannel.EnableLights(true);
            notificationChannel.EnableVibration(true);
            notificationChannel.SetVibrationPattern(new long[] { 100, 200, 300, 400, 500, 400, 300, 200, 400 });
    
    
            NotificationManager notificationManager = (NotificationManager)this.GetSystemService(Context.NotificationService);
            notificationManager.CreateNotificationChannel(notificationChannel);
        }
    
        //start a foreground notification to keep alive 
        private void DispatchNotificationThatServiceIsRunning()
        {
            NotificationCompat.Builder builder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID)
                   .SetDefaults((int)NotificationDefaults.All)
                   .SetSmallIcon(Resource.Drawable.Icon)
                   .SetVibrate(new long[] { 100, 200, 300, 400, 500, 400, 300, 200, 400 })
                   .SetSound(null)
                   .SetChannelId(NOTIFICATION_CHANNEL_ID)
                   .SetPriority(NotificationCompat.PriorityDefault)
                   .SetAutoCancel(false)
                   .SetContentTitle("Mobile")
                   .SetContentText("My service started")
                   .SetOngoing(true);
    
            NotificationManagerCompat notificationManager = NotificationManagerCompat.From(this);
            StartForeground(NOTIFICATION_SERVICE_ID, builder.Build());
        }
    
        //every 5 seconds push a notificaition
        private void DispatchNotificationThatAlarmIsGenerated(string message)
        {
            var intent = new Intent(this, typeof(MainActivity));
            intent.AddFlags(ActivityFlags.ClearTop);
            var pendingIntent = PendingIntent.GetActivity(this, 0, intent, PendingIntentFlags.OneShot);
    
            Notification.Builder notificationBuilder = new Notification.Builder(this, NOTIFICATION_CHANNEL_ID)
                .SetSmallIcon(Resource.Drawable.Icon)
                .SetContentTitle("Alarm")
                .SetContentText(message)
                .SetAutoCancel(true)
                .SetContentIntent(pendingIntent);
    
            var notificationManager = (NotificationManager)GetSystemService(NotificationService);
            notificationManager.Notify(NOTIFICATION_AlARM_ID, notificationBuilder.Build());
        }
    }
    

    2.在你的活动中:

    protected override void OnResume()
      {
          base.OnResume();
          StartMyRequestService();
      }
    public void StartMyRequestService()
      {
          var serviceToStart = new Intent(this, typeof(MyService));
          StartService(serviceToStart);
      }
    

    【讨论】:

    • 好的 Leo 非常感谢 :) 我做了这个解决方案,效果很明显,但我需要 android 和 iOS 这仅适用于 android 我们可以在 iOS 上做什么来做某事?
    • @Onurİn 我对 ios 了解不多,恐怕 ios 做不到
    猜你喜欢
    • 1970-01-01
    • 2016-09-24
    • 2020-03-16
    • 1970-01-01
    • 2017-12-14
    • 1970-01-01
    • 2019-10-31
    • 1970-01-01
    • 2016-08-15
    相关资源
    最近更新 更多