powered by simpleCommunicator - 2.0.34     © 2025 Programmizd 02
Форумы / Разработка под мобильные платформы [игнор отключен] [закрыт для гостей] / Передача данных из Service в Activity Xamarin Android
1 сообщений из 1, страница 1 из 1
Передача данных из Service в Activity Xamarin Android
    #39701969
vb_sub
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всем привет, никак не могу сделать рабочую схему передачи данных из сервиса в Activite. Смысл такой: есть сервис, который все время слушает сообщения от SignalR, даже когда устройство заблокировано. Если пришли данные от SignalR, то сохраняем их и при выходе мобильного устройства из заблокированного состояния обновляем Activity новыми пришедшими данными. При гуглении нашел почти рабочую схему Service+BroadCaster+ ссылка на Activity. Реализовал следующим образом:

Код сервиса
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
[Service]
    public class SignalRService : Service
    {
        HubConnection signalRconnection;
        const int NOTIFICATION_ID = 9000;
        string selectedItemId = "q45514";
        const string baseUrl = "http://11.11.1.111:100";

        private    DataReceiver mDataReceiver;

        Intent mobilszDataReceiverIntent;
        #region privateVar


        #endregion

        public override IBinder OnBind(Intent intent)
        {
            return (null);
        }

        public SignalRService()
        {
        }

        public async override void OnStart(Intent intent, int startId)
        {
            await InitializeSignalRHub();
            base.OnStart(intent, startId);         
        }


        public override void OnCreate()
        {
            base.OnCreate();     
            mobilszDataReceiverIntent = new Intent("mobilszDataReceiver");
        }

 
        private async Task InitializeSignalRHub()
        {
            try
            {
                signalRconnection = new HubConnectionBuilder()
                            .WithUrl(baseUrl + "/broadcaster", options =>
                            {
                            })
                            .Build();

                signalRconnection.Closed += Connection_Closed;

                await ConnectToSignalRServer();
            }
            catch (Exception ex)
            {
                throw;
            }
        }

        private async Task<bool> ConnectToSignalRServer()
        {
            bool connected = false;
            try
            {
                    signalRconnection.On<reportItem>("ReceiveReport", async (_reports) =>
                    {                                         
                        string JsonReports = JsonConvert.SerializeObject(_reports);
                        mobilszDataReceiverIntent.PutExtra("JsonReport", JsonReports);
                        SendBroadcast(mobilszDataReceiverIntent);
                    });               

                    await signalRconnection.StartAsync();
                    connected = true;       

                return connected;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error {ex.Message}");
                return false;
            }
        }

        private async Task Connection_Closed(Exception arg)
        {

            Notification.Builder notificationBuilder = new Notification.Builder(this)
           .SetContentTitle("Connection_Closed")
           .SetContentText("Connection_Closed");

            var notificationManager = (NotificationManager)GetSystemService(NotificationService);
            notificationManager.Notify(NOTIFICATION_ID, notificationBuilder.Build());


            bool isConnected = false;
            while (!isConnected)
            {
                //делаем задержку в 1 секунду
                await Task.Delay(1000);
                try
                {
                    await signalRconnection.StartAsync();
                    isConnected = true;
                    return;
                }
                catch (Exception)
                {
                }
            }
        }

        public override void OnDestroy()
        {
            base.OnDestroy();

            UnregisterReceiver(mDataReceiver);
            mDataReceiver = null;
        }   
    }



Код BroadcastReceiver:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
[BroadcastReceiver(Enabled = true, Exported = false)]
    [IntentFilter(new[] { "mobilszDataReceiver" })]

    public class DataReceiver : BroadcastReceiver
    {

        /// <summary>
        /// Последний набор данных, который посылали в ReportListActivity
        /// </summary>
        /// 

        reportItem LastReportItem { get;  set; }

        bool IsActivityPaused;

        ReportListActivity mReportListActivity;

        public DataReceiver(ReportListActivity Activity)
        {
            mReportListActivity = Activity;
            mReportListActivity.ActOnResume += MReportListActivity_ActOnResume;
            mReportListActivity.ActOnPause += MReportListActivity_ActOnPause;
        }

        private void MReportListActivity_ActOnPause(reportItem reportItem)
        {
            IsActivityPaused = true;
        }

        private void MReportListActivity_ActOnResume(reportItem reportItem)
        {
            IsActivityPaused = false;

            if (LastReportItem == null)
                return;

            if (reportItem == null || !reportItem.Equals(LastReportItem))
                mReportListActivity.ReceivedSz(LastReportItem);
            
        }
     
        public DataReceiver()
        {

        }

        public override void OnReceive(Context context, Intent intent)
        {
            reportItem deserializedReportItem = JsonConvert.DeserializeObject<reportItem>(intent.GetStringExtra("JsonReport"));
            LastReportItem = deserializedReportItem;

            //если новый список <reportItem> и приложение в не остановленном состоянии
            if (mReportListActivity != null || !IsActivityPaused)
            {               
                 mReportListActivity.ReceivedSz(deserializedReportItem);
            }
       }
    }



Код Activity
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
public class ReportListActivity :ListActivity
    {

        DataReceiver dataReceiver;


        #region Events
        public delegate void ReportListActivityOnResume(reportItem reportItem);
        public event ReportListActivityOnResume ActOnResume;


        public delegate void ReportListActivityOnPause(reportItem reportItem);
        public event ReportListActivityOnPause ActOnPause;

        #endregion

        /// <summary>
        /// Последний набор данных, который хранится в ReportListActivity
        /// </summary>
        /// 

        public reportItem LastReportItem { get;private set; }


        protected override async void OnCreate(Bundle savedInstanceState)
        {
     
            base.OnCreate(savedInstanceState);
            SetContentView(Resource.Layout.reportList);

    
            dataReceiver = new DataReceiver(this);


            try
            {
                //SignalR service
                Intent i = new Intent(this, typeof(SignalRService));
                this.StartService(i);
            }
            catch (Exception sd)
            {
                throw;
            }            
        } 

        public void ReceivedSz(reportItem _reports)
        {
            LastReportItem = _reports
            RunOnUiThread(delegate
            {
                ListAdapter = new ReportAdapter(_reports.fltList);
                FIOText.Text = _reports.driver.F;
            });
        }

        protected override void OnResume()
        {
             ActOnResume?.Invoke(LastReportItem);
            base.OnResume();
            RegisterReceiver(dataReceiver, new IntentFilter("mobilszDataReceiver"));
        }

        protected override void OnPause()
        {
            ActOnPause?.Invoke(LastReportItem);
            UnregisterReceiver(dataReceiver);
            base.OnPause();
        }  
    }


Проблема в том, что когда осуществляется вызов SendBroadcast(mobilszDataReceiverIntent);
DataReceiver пересоздается заново и соответственно ссылка на Activity теряется(вызывается пустой DataReceiver).
Как можно это проблему обойти? Спасибо
...
Рейтинг: 0 / 0
1 сообщений из 1, страница 1 из 1
Форумы / Разработка под мобильные платформы [игнор отключен] [закрыт для гостей] / Передача данных из Service в Activity Xamarin Android
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]