Я разрабатываю приложение для видеовызовов в Xamarin Forms, где пользователь может звонить другому пользователю через API Agora. С iOS я могу использовать CallKit, чтобы показать входящий вызов пользователю, но как мне показать входящий вызов пользователю android? Я могу поймать уведомление pu sh, используя Azure Центр уведомлений, но как мне показать представление входящего вызова на моем Android устройстве?
РЕДАКТИРОВАТЬ: Я сделал некоторый прогресс, но я все еще не там ... Я создал интерфейс INotificationService в моем общем проекте.
public interface INotificationService
{
Task<NotificationHubResponse> RegisterNotification(string accessToken, string userId);
void HandleNotification(IDictionary<string, string> data);
}
Используя DependencyService, я могу реализовать этот интерфейс в своих Android (и iOS) project.
[assembly: Dependency(typeof([Namespace].Mobile.Droid.Services.NotificationService))]
namespace [Namespace].Mobile.Droid.Services
{
public class NotificationService : INotificationService
{
public async Task<NotificationHubResponse> RegisterNotification(string accessToken, string userId)
{
//Custom implementation to get FCM token and register on the Azure notification hub
}
public void HandleNotification(IDictionary<string, string> data)
{
// Code ommitted where I check what type of notification this is to make it less complex...
var callNotificationIntent = new Intent(CrossCurrentActivity.Current.AppContext, typeof(CallNotificationActivity));
callNotificationIntent.SetFlags(ActivityFlags.ClearWhenTaskReset | ActivityFlags.NewTask);
callNotificationIntent.PutExtra("CallingName", callerName.Value);
callNotificationIntent.PutExtra("CallerId", callerId.Value);
callNotificationIntent.PutExtra("RoomId", roomId.Value);
CrossCurrentActivity.Current.AppContext.StartActivity(callNotificationIntent);
}
}
}
}
Это открывает настраиваемое действие с макетом, который напоминает макет вызова (имя абонента, кнопка подтверждения вызова и кнопка отказа в вызове). Все идет нормально. Это действие всегда открывается, когда я получаю уведомление pu sh, когда приложение активно или находится в фоновом режиме (все еще нужно тестировать / внедрять, когда приложение не активно). Когда я нажимаю кнопку «Принять вызов», я вызываю следующий метод (в моем классе Android Activity).
private async void OnClickAccept()
{
//Some code to prepare my call. Removed because company code...
var mainActivityIntent = new Intent(CrossCurrentActivity.Current.AppContext, typeof(MainActivity))
.AddFlags(ActivityFlags.ReorderToFront)
.PutExtra("OpenPage", "ConsultationPage")
.PutExtra("RoomId", _roomId.ToLower());
CrossCurrentActivity.Current.AppContext.StartActivity(mainActivityIntent);
CloseView();
}
В моей функции MainActivity в Oncreate () я добавил следующий код для перехвата Дополнения добавлены в Intent.
//Background or killed mode
if (Intent.Extras != null)
{
foreach (var key in Intent.Extras.KeySet())
{
var value = Intent.Extras.GetString(key);
if (key == "OpenPage")
{
if (value?.Length > 0 && value == "ConsultationPage")
{
isNotification = true;
LoadApplication(new App(value, Intent.Extras.GetString("RoomId")));
} else
{
isNotification = true;
LoadApplication(new App(value, string.Empty));
}
}
}
}
//Normal loading
if (!isNotification)
{
LoadApplication(new App(string.Empty, string.Empty));
}
И, наконец, в моем app.xaml.cs (общий проект) я изменил конструктор приложения на этот.
public App (string viewName, string roomId)
{
this.InitializeComponent ();
Startup.Init ();
var rootPage = new NavigationPage(new LoginPage());
NavigationPage.SetHasBackButton(rootPage, false);
MainPage = rootPage;
if (!string.IsNullOrWhiteSpace(viewName))
{
if (viewName == "ConsultationPage")
{
var uid = Convert.ToUInt32(Xamarin.Forms.Application.Current.Properties["UId"]);
Current.MainPage.Navigation.PushModalAsync(new ConsultationPage(new ConsultationViewModel(roomId, uid)));
}
}
}
Итак здесь это терпит неудачу. Я получаю следующую ошибку, когда нажимаю кнопку «Принять вызов»:
Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?
Когда я добавляю этот флаг к своему намерению, он иногда работает ... Иногда приложение открывается второй раз и показывает мне мой при входе в систему, но я вижу, что (первое) приложение открыло мою страницу консультаций, когда начался видеочат агоры (я вижу это в журналах). Если я нажимаю кнопку «Назад» на моем устройстве, второе приложение закрывается, и я вижу правильную страницу.
Иногда ничего не происходит. И иногда все работает. Это очень случайно, когда я отлаживаю это работает. Если я открываю одно и то же приложение на устройстве без подключения к Visual Studio, оно не открывается. На Samsung Galaxy я получаю другой результат, чем на своем OnePlus.
Я подозреваю, что это как-то связано с флагом NEW_TASK, поскольку я нашел несколько сообщений, в которых говорится, что вы должны избегать использования этого флага. Я пытался изменить контекст намерения на «это», но продолжаю получать ту же ошибку.