Я пытаюсь создать обработчик, который будет генерировать всплывающее окно при получении сообщения от 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);
}
}
Это все работает, как и ожидалось, мне все еще нужно поработать, чтобы очистить его, но оно работает. Я могу подключиться к концентратору сервера и отправлять сообщения нужным группам людей. Теперь мне нужно, чтобы это работало в качестве службы переднего плана.