У меня есть служба (фоновая), при запуске приложения она включается и отображается в шторке уведомлений , как рабочая. Она подключается к сокету, слушает его а так же в цикле проверяет наличие соединения. Весь функционал отлично работает, как с закрытым так и открытым приложением. Проверил , служба действительно работала несколько дней ничего не выключалось.
К сути - Решил сделать BroadcastReceiver на перезагрузку устройства. Столкнулся с проблемой, что когда Broadcast Receiver запускает службу , он не может подключится к сокету и вылетает на этом моменте MyWebSocket.Connect()
Вот код Receiver
[BroadcastReceiver(Name = "com.companyname.corporate_messenger.BootReceiver", Enabled = true, Exported = true)]
[IntentFilter(new[] { Android.Content.Intent.ActionBootCompleted })]
public class BootReceiver : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
var intentService = new Intent(context, typeof(NotoficationService));
if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.O)
{
context.StartForegroundService(intentService);
}
else
{
context.StartService(intentService);
// Flag_On_Off_Service = true;
}
} // OnReceive
}
У меня есть служба (фоновая), при запуске приложения она включается и отображается в шторке уведомлений , как рабочая. Она подключается к сокету, слушает его а так же в цикле проверяет наличие соединения. Весь функционал отлично работает, как с закрытым так и открытым приложением. Проверил , служба действительно работала несколько дней ничего не выключалось.
К сути - Решил сделать BroadcastReceiver на перезагрузку устройства. Столкнулся с проблемой, что когда Broadcast Receiver запускает службу , он не может подключится к сокету и вылетает на этом моменте MyWebSocket.Connect()
Вот код Receiver
[BroadcastReceiver(Name = "com.companyname.corporate_messenger.BootReceiver", Enabled = true, Exported = true)]
[IntentFilter(new[] { Android.Content.Intent.ActionBootCompleted })]
public class BootReceiver : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
var intentService = new Intent(context, typeof(NotoficationService));
if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.O)
{
context.StartForegroundService(intentService);
}
else
{
context.StartService(intentService);
// Flag_On_Off_Service = true;
}
} // OnReceive
}
Вот код службы
[Service(Exported = true)]
public class NotoficationService : Android.App.Service
{
// address
private string address = "адрес:6001";
// ID Уведомления о включении службы
public const int ServiceRunningNotifID = 9001;
// Сокет
GetSocket socket = new GetSocket();
// Локальные уведомления для сообщений
private NotificationMessage NotificationMessageManager;
NotificationHelper helper = new NotificationHelper();
// Локальные уведомления для Звонков
private NotificationCall NotificationCalllManager = new NotificationCall();
// Пользователь
private UserDataModel MyUser;
Notification notif;
public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
{
// Запуск сервиса
notif = helper.ReturnNotif();
StartForeground(ServiceRunningNotifID, notif);
NotificationMessageManager = new NotificationMessage();
NotificationMessageManager.NotificationReceived += (sender, eventArgs) =>
{
var evtData = (Service.Notification.NotificationEventArgs)eventArgs;
ShowNotification(evtData.Title, evtData.Message);
};
NotificationCalllManager.NotificationReceived += (sender, eventArgs) =>
{
var evtData = (Service.Notification.NotificationEventArgs)eventArgs;
ShowNotification(evtData.Title, evtData.Message);
};
// создаем новый поток
Thread myThread = new Thread(MyTimer);
// запускаем поток myThread
myThread.Start();
return StartCommandResult.Sticky;
}
string status = "";
private void MyTimer()
{
socket.MyWebSocket = new WebSocketSharp.WebSocket("ws://" + address);
socket.MyWebSocket.WaitTime = TimeSpan.FromSeconds(5.0);
socket.MyWebSocket.OnMessage += Ws_OnMessage;
socket.MyWebSocket.OnOpen += Ws_OnOpen;
socket.MyWebSocket.OnClose += Ws_OnClose;
socket.MyWebSocket.OnError += Ws_OnError;
var countPing = 0;
while (true)
{
try
{
bool ping = socket.MyWebSocket.Ping();
if (!ping)
{
// Тут вылетает - но не падает служба!
socket.MyWebSocket.Connect();
ping = socket.MyWebSocket.Ping();
if (ping)
{
if (status != "Соединение установлено")
{
status = "Соединение установлено";
// Toast.MakeText(Android.App.Application.Context, "Подключился", ToastLength.Short).Show();
helper.NewNotif(status);
DependencyService.Get<IForegroundService>().Flag_On_Off_Socket = true;
}
}
else
{
countPing++;
if (countPing == 15)
{
countPing = 0;
socket.MyWebSocket.Close();
socket.MyWebSocket = new WebSocketSharp.WebSocket("ws://" + address);
socket.MyWebSocket.OnMessage += Ws_OnMessage;
socket.MyWebSocket.OnOpen += Ws_OnOpen;
socket.MyWebSocket.OnClose += Ws_OnClose;
socket.MyWebSocket.OnError += Ws_OnError;
}
if (status != "Соединение не установлено, настраиваем соединение")
{
status = "Соединение не установлено, настраиваем соединение";
helper.NewNotif(status);
}
DependencyService.Get<IForegroundService>().Flag_On_Off_Socket = false;
// Toast.MakeText(Android.App.Application.Context, "Не Подключился", ToastLength.Short).Show();
}
}
}
catch (Exception e)
{
string errMsg = e.Message.ToString();
if (errMsg.Equals("The current state of the connection is not Open."))
{// remote host does not exist
// Toast.MakeText(Android.App.Application.Context, "Подключение сбилось ", ToastLength.Short).Show();
// Console.WriteLine(string.Format("Failed to connect to {0}:{1}", host, port));
DependencyService.Get<IForegroundService>().Flag_On_Off_Socket = false;
if (status != "Соединение не установлено, настраиваем соединение")
{
status = "Соединение не установлено, настраиваем соединение ";
helper.NewNotif(status);
}
}
if (errMsg.Equals("A series of reconnecting has failed."))
{// refusal of ws object to reconnect; create new ws-object
DependencyService.Get<IForegroundService>().Flag_On_Off_Socket = false;
if (status != "Соединение не установлено, настраиваем соединение")
{
status = "Соединение не установлено, настраиваем соединение";
helper.NewNotif(status);
}
socket.MyWebSocket.Close();
socket.MyWebSocket = new WebSocketSharp.WebSocket("ws://" + address);
socket.MyWebSocket.OnMessage += Ws_OnMessage;
socket.MyWebSocket.OnOpen += Ws_OnOpen;
socket.MyWebSocket.OnClose += Ws_OnClose;
socket.MyWebSocket.OnError += Ws_OnError;
}
else
{// any other exception
Toast.MakeText(Android.App.Application.Context, e.Message, ToastLength.Short).Show();
// Thread.Sleep(3000);
}
}
}
}
}
}
Судя по документации Microsoft служба работает правильно , Receiver то же запускается правильно , я так же зарегал его в манифесте. Если убрать строку MyWebSocket.Connect() то служба полностью запускается и даже показывает уведомления , только вот сам сокет остается не запущенным
Выяснил что падает такая ошибка You must call Xamarin.Forms.Forms.Init(); prior to using this property.