@DS2107

Как в BroadCast Receiver включить сокет?

У меня есть служба (фоновая), при запуске приложения она включается и отображается в шторке уведомлений , как рабочая. Она подключается к сокету, слушает его а так же в цикле проверяет наличие соединения. Весь функционал отлично работает, как с закрытым так и открытым приложением. Проверил , служба действительно работала несколько дней ничего не выключалось.

К сути - Решил сделать 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.
  • Вопрос задан
  • 95 просмотров
Пригласить эксперта
Ответы на вопрос 1
402d
@402d
начинал с бейсика на УКНЦ в 1988
https://developer.android.com/guide/components/int...
первое что броилось в глаза typeof
Для javы передается класс
Intent downloadIntent = new Intent(this, DownloadService.class);
вариант для котлин
val downloadIntent = Intent(this, DownloadService::class.java)
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы