|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|