показать всплывающее сообщение от службы - PullRequest
0 голосов
/ 01 июня 2019

Я пытаюсь создать обработчик, который будет генерировать всплывающее окно при получении сообщения от SignalR, который работает в службе. У меня это работает в не-сервисе, но не работает в сервисе.

Этот код работает без обслуживания:

client.OnMessageReceived += 
(sender2, message) => 
RunOnUiThread(() =>
showMessage(message));

Где client - это клиент SignalR, а showMessage - это метод, вызываемый при получении сообщения от клиента. Нет проблем.

Теперь я хочу запустить клиент в / как сервис, и мне нужно подключить обработчик, чтобы сделать в основном то же самое. Я пробовал несколько методов, которые я нашел на StackOverflow и других сайтах, но все, что есть, это java, а не c # для Xamarin для Visual Studio (2017) и не очень хорошо переводится. Я в растерянности относительно того, как действовать.

* Обновление * Это мой код обслуживания:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Acr.UserDialogs;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Support.V4.App;
using Android.Views;
using Android.Widget;
using ChatClient.Shared;
using Java.Lang;

namespace OML_Android
{
    public class SignalRService : Service
    {
        public const int SERVICE_RUNNING_NOTIFICATION_ID = 10000;
        public const string ACTION_MAIN_ACTIVITY = "OML_Android.action.MainActivity";
        public const string SERVICE_STARTED_KEY = "has_service_been_started";

        bool isStarted;
        Handler handler;
        Action runnable;

        // This information will eventually be pulled from the intent, this is just for testing
        public string firstname = "";
        public string lastname = "";
        public string username = "";
        public string name = "";

        private Client mInstance;

        public override IBinder OnBind(Intent intent)
        {
            return null;
            // throw new NotImplementedException();
        }

        public override void OnCreate()
        {
            base.OnCreate();
            mInstance = Client.Getinstance(name, username, firstname, lastname);
            mInstance.Connect();
        }

        public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
        {
            return StartCommandResult.Sticky;
        }
        public override void OnDestroy()
        {
            // Not sure what to do here yet, got to get the service working first
        }
        void RegisterForegroundService()
        {
            var notification = new NotificationCompat.Builder(this)
                .SetContentTitle(Resources.GetString(Resource.String.app_name))
                .SetContentText(Resources.GetString(Resource.String.notification_text))
                .SetSmallIcon(Resource.Drawable.alert_box)
                .SetContentIntent(BuildIntentToShowMainActivity())
                .SetOngoing(true)
                //.AddAction(BuildRestartTimerAction())
                //.AddAction(BuildStopServiceAction())
                .Build();


            // Enlist this instance of the service as a foreground service
            StartForeground(SERVICE_RUNNING_NOTIFICATION_ID, notification);
        }

        PendingIntent BuildIntentToShowMainActivity()
        {
            var notificationIntent = new Intent(this, typeof(MainActivity));
            notificationIntent.SetAction(ACTION_MAIN_ACTIVITY);
            notificationIntent.SetFlags(ActivityFlags.SingleTop | ActivityFlags.ClearTask);
            notificationIntent.PutExtra(SERVICE_STARTED_KEY, true);

            var pendingIntent = PendingIntent.GetActivity(this, 0, notificationIntent, PendingIntentFlags.UpdateCurrent);
            return pendingIntent;
        }

        public async void showMessage(string message)
        {

            var result = await UserDialogs.Instance.ConfirmAsync(new ConfirmConfig
            {
                Message = "Text Message from Company: " + System.Environment.NewLine + message,
                OkText = "Ok",

            });
            if (result)
            {
                // do something
                var x = message;
            }
        }
    }
}

Эта служба устанавливает клиент для работы в качестве службы переднего плана (я полагаю), код клиента:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;

using System.Threading.Tasks;
using Microsoft.AspNet.SignalR.Client;

namespace ChatClient.Shared
{
    public sealed class Client
    {
        //public string username;
        private string username = "";
        private string _platform = "";
        private readonly HubConnection _connection;
        private readonly IHubProxy _proxy;

        public string _Username
        {
            get { return username; }
            set { username = value; }
        }

        public string _Platform
        {
            get { return _platform; }
            set { _platform = value; }
        }

        public event EventHandler<string> OnMessageReceived;
        public static Client instance = null;

        public Client(string name, string username, string firstname, string lastname, string company, string department, string section)
        {
            _Username = username;
            _Platform = name;
            _platform = _Platform;

            Dictionary<string, string> queryString = new Dictionary<string, string>();
            queryString.Add("username", username);
            queryString.Add("firstname", firstname);
            queryString.Add("lastname", lastname);
            queryString.Add("company", company);
            queryString.Add("department", department);
            queryString.Add("section", section);

            _connection = new HubConnection("https://www.example.com/SignalRhub",queryString );

            _proxy = _connection.CreateHubProxy("chathub");
        }

        public static Client Getinstance(string name, string username, string firstname, string lastname)
        {
            // create the instance only if the instance is null
            if (instance == null)
            {
                // The username and user's name are set before instantiation
                instance = new Client(name, username, firstname, lastname,"","","");
            }
            // Otherwise return the already existing instance
            return instance;
        }
        public async Task Connect()
        {

            await _connection.Start(); //.ContinueWith._connection.server.registerMeAs("");
            _proxy.On("broadcastMessage", (string platform, string message) =>
            {
                if (OnMessageReceived != null)
                    OnMessageReceived(this, string.Format("{0}: {1}", platform, message));
            });

            // Send("Connected");
        }

        public async Task<List<string>> ConnectedUsers()
        {

            List<string> Users = await _proxy.Invoke<List<string>>("getConnectedUsers");

            return Users;
        }

        public async Task<List<string>> ConnectedSectionUsers(string company, string department, string section, string username)
        {

            List<string> Users = await _proxy.Invoke<List<string>>("getConnectedSectionUsers",company, department, section, username);

            return Users;
        }

        public Task Send(string message)
        {
            return _proxy.Invoke("Send", _platform, message);
        }

        public Task SendSectionMessage(string company, string department, string section, string name, string message)
        {
            return _proxy.Invoke("messageSection", company,  department,  section,  name,  message);
        }

        public Task SendCompanyMessage(string company, string department, string section, string name, string message)
        {
            return _proxy.Invoke("messageCompany", company, name, message);
        }

    }
}

Это код, который я планирую использовать для запуска службы (пока не работает), я буду добавлять информацию в намерение через intent.PutExtras, а именно: Имя, фамилия, имя пользователя, имя, компания, отдел и раздел. На данный момент я просто установил для них пустую строку в сервисе в целях тестирования.

    public static void StartForegroundServiceComapt<SignalRService>(this Context context, Bundle args = null) where SignalRService : Service
    {
        var intent = new Intent(context, typeof(SignalRService));
        if (args != null)
        {
            intent.PutExtras(args);
        }

        if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.O)
        {
            context.StartForegroundService(intent);
        }
        else
        {
            context.StartService(intent);
        }
    }

Это все работает, как и ожидалось, мне все еще нужно поработать, чтобы очистить его, но оно работает. Я могу подключиться к концентратору сервера и отправлять сообщения нужным группам людей. Теперь мне нужно, чтобы это работало в качестве службы переднего плана.

1 Ответ

0 голосов
/ 05 июня 2019

Создает ли ваше приложение канал уведомлений?Вы должны передавать идентификатор канала уведомления конструктору NotificationCompat.Builder.

Не похоже, что вы вызываете метод RegisterForegroundService для продвижения службы в службу переднего плана.Вы захотите позвонить RegisterForegroundService в начале переопределения OnCreate.Современные версии Android требуют, чтобы служба переднего плана показывала уведомление в течение нескольких секунд, иначе будет выдано исключение.

Возможно, вы захотите добавить разрешение android.permission.FOREGROUND_SERVICE в свой манифест Android, поскольку оно требуется для Android P ипозже.

Я не думаю, что ACR.UserDialogs будет работать, если ваше приложение не имеет текущей верхней активности.Служба переживает действие, поэтому очень возможно столкнуться с этим сценарием.Вы можете просто попросить службу обновить существующее уведомление переднего плана, чтобы показать пользователю, что новое сообщение доступно.

...