using Android.App; using Android.Content; using Android.OS; using Android.Runtime; using AndroidX.Core.App; using GMCabsDriverAssistant.Messages; using GMCabsDriverAssistant.Services; using GMCabsDriverAssistantSolution.Platforms.Android.Services; using Sentry; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; [assembly: Dependency(typeof(AndroidLocationService))] namespace GMCabsDriverAssistantSolution.Platforms.Android.Services { [Service(Enabled = true)] public class AndroidLocationService : Service, IForegroundService { CancellationTokenSource _cts; public const int SERVICE_RUNNING_NOTIFICATION_ID = 10000; public static bool IsForegroundServiceRunning; public override IBinder OnBind(Intent intent) { return null; } [return: GeneratedEnum] public override StartCommandResult OnStartCommand(Intent intent, [GeneratedEnum] StartCommandFlags flags, int startId) { string foregroundChannelId = "GMCabsForeGroundServiceChannel"; _cts = new CancellationTokenSource(); Task.Run(() => { while (IsForegroundServiceRunning) { try { var locShared = new LocationService(); locShared.Run(_cts.Token).Wait(); } catch (System.OperationCanceledException oce) { SentrySdk.CaptureException(oce); } finally { if (_cts.IsCancellationRequested) { var message = new StopServiceMessage(); Device.BeginInvokeOnMainThread( () => DependencyService.Resolve().StopMyForegroundService() ); } } } }, _cts.Token); var notifManager = this.GetSystemService(global::Android.Content.Context.NotificationService) as NotificationManager; var pendingIntentFlags = (Build.VERSION.SdkInt >= BuildVersionCodes.S) ? PendingIntentFlags.UpdateCurrent | PendingIntentFlags.Mutable : PendingIntentFlags.UpdateCurrent; var pendingActivityIntent = PendingIntent.GetActivity(this, 0, intent, pendingIntentFlags); var pendingIntent = PendingIntent.GetBroadcast(this, 0, intent, pendingIntentFlags); var notificationBuilder = new NotificationCompat.Builder(this, foregroundChannelId) .SetContentTitle("Location") .SetContentText("Update location") .SetPriority(1) .SetOngoing(true) .SetAutoCancel(true) .SetContentIntent(pendingIntent); if (global::Android.OS.Build.VERSION.SdkInt >= global::Android.OS.BuildVersionCodes.O) { var notificationChannel = new NotificationChannel(foregroundChannelId, "Title", NotificationImportance.High); notificationChannel.Importance = NotificationImportance.High; notificationChannel.EnableLights(true); notificationChannel.EnableVibration(true); notificationChannel.SetShowBadge(true); notificationChannel.SetVibrationPattern(new long[] { 100, 200, 300 }); if (notificationBuilder != null) { notificationBuilder.SetChannelId(foregroundChannelId); notifManager.CreateNotificationChannel(notificationChannel); } } // Notification notif = DependencyService.Get().ReturnNotif(); StartForeground(SERVICE_RUNNING_NOTIFICATION_ID, notificationBuilder.Build()); return base.OnStartCommand(intent, flags, startId); } public override void OnCreate() { base.OnCreate(); IsForegroundServiceRunning = true; } public override void OnDestroy() { IsForegroundServiceRunning = false; if (_cts != null) { _cts.Token.ThrowIfCancellationRequested(); _cts.Cancel(); } base.OnDestroy(); } public void StartMyForegroundService() { var intent = new Intent(global::Android.App.Application.Context, typeof(AndroidLocationService)); if (global::Android.OS.Build.VERSION.SdkInt >= global::Android.OS.BuildVersionCodes.O) { global::Android.App.Application.Context.StartForegroundService(intent); } else { global::Android.App.Application.Context.StartService(intent); } } public void StopMyForegroundService() { var intent = new Intent(global::Android.App.Application.Context, typeof(AndroidLocationService)); global::Android.App.Application.Context.StopService(intent); } public bool IsForeGroundServiceRunning() { return IsForegroundServiceRunning; } } }