using Android.App; using Android.Content; using Android.OS; using Android.Runtime; using Android.Views; using Android.Widget; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using PhilExample.Droid.Services; using PhilExample.Droid.Utils; using PhilExample.Interfaces; using PhilExample.Services; [assembly: Xamarin.Forms.Dependency(typeof(ForegroundTCPService))] namespace PhilExample.Droid.Services { [Service] public class ForegroundTCPService : Service, IForegroundTCPService { private static IForegroundTCPDelegate _tcpDelegate; private static readonly int _notiID = 1; private static bool _running = false; const string NOTIFICATION_CHANNEL_ID = "1"; const string NOTIFICATION_CHANNEL_NAME = "PhilExample_noti_1"; const string NOTIFICATION_CHANNEL_DESCR = "PhilExample_foreground"; public bool IsRunning => _running; #region IForegroundTCPService public void Start(IForegroundTCPDelegate del) { _tcpDelegate = del; if (_running) UpdateNotification(); else { StartService(); _running = true; } } public void UpdateNotification() { NotificationHelper.GetAndroidNotificationManager().Notify(_notiID, CreateNotification()); } public void Stop() { //StopForeground(StopForegroundFlags.Remove); var fgIntent = new Intent(MainActivity._THIS, typeof(ForegroundTCPService)); MainActivity._THIS.StopService(fgIntent); _running = false; } #endregion private void StartService() { var intent = new Intent(MainActivity._THIS, typeof(ForegroundTCPService)); if (Build.VERSION.SdkInt >= BuildVersionCodes.O) MainActivity._THIS.StartForegroundService(intent); else MainActivity._THIS.StartService(intent); } public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId) { if (_tcpDelegate == null) //TODO throw new NotImplementedException("Android ForegroundTCPService.StartCommandResult"); Console.WriteLine("Starting foregorund tcp service with _notiID: " + _notiID); NotificationHelper.CreateNotificationChannel(NOTIFICATION_CHANNEL_ID, NOTIFICATION_CHANNEL_NAME, NOTIFICATION_CHANNEL_DESCR); StartForeground(_notiID, CreateNotification()); Task.Run(() => { Console.WriteLine("[" + DateTime.Now.TimeOfDay.ToString().Substring(0, 8) + "] (" + _notiID + ") tcp foreground service started"); _tcpDelegate.ReceiveLoop(); _tcpDelegate.OnForegroundStop(); Console.WriteLine("[" + DateTime.Now.TimeOfDay.ToString().Substring(0, 8) + "] (" + _notiID + ") tcp foreground service finished"); }); return StartCommandResult.Sticky; } public override void OnDestroy() { _running = false; Console.WriteLine("tcp foreground service OnDestroy was called."); base.OnDestroy(); } public override void OnTaskRemoved(Intent rootIntent) { _running = false; Console.WriteLine("tcp foreground service OnTaskRemoved was called."); base.OnTaskRemoved(rootIntent); } private Notification CreateNotification() { string msgTitle = _tcpDelegate.GetForegroundNotificationTitle; string msgDescr = _tcpDelegate.GetForegroundNotificationDescription; Intent notificationIntent = new Intent(MainActivity._THIS, typeof(MainActivity)); var onClickIntent = PendingIntent.GetActivity(MainActivity._THIS, 0, notificationIntent, PendingIntentFlags.UpdateCurrent); var notification = new Notification.Builder(MainActivity._THIS, NOTIFICATION_CHANNEL_ID) .SetContentIntent(onClickIntent) .SetContentTitle(msgTitle) .SetContentText(msgDescr) .SetSmallIcon(Resource.Drawable.abc_ab_share_pack_mtrl_alpha) .SetOngoing(true) .Build(); return notification; } public override IBinder OnBind(Intent intent) => null; } }