Не работают кнопки в уведомлении, как исправить?
Я делаю приложение - мессенджер. Когда я совершаю звонок через мессенджер появляется уведомление о звонке, это уведомление я сделал кастомное - добавил 2 кнопки(ответить сбросить) и имя пользователя который звонит. Когда уведомление отображается на некоторых устройствах кнопки работают , а на некоторых нет. При нажатии на кнопку срабатывает Ресивер, код ресивера я думаю не обязательно показывать так как в нем происходят действия после нажатия (эти действия работают и проверены на других устройствах ). В основном такая проблема встречается на Samsung , создается ощущение что приложение не подхватывает id кнопок.
Вот мой код layout
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/rl"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#F0F0F0"
android:minWidth="25px"
android:minHeight="25px">
<refractored.controls.CircleImageView
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/profile_image"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="50dp"
android:layout_width="96dp"
android:layout_height="96dp"
android:src="@drawable/kot"
/>
<TextView
android:id="@+id/Name"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Имя пользователя"
android:layout_marginTop="160dp"
android:textSize="@dimen/abc_dialog_padding_material"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxHeight="25px"
android:maxWidth="25px"
android:id="@+id/imageView1"
/>
<TextView
android:id="@+id/MyTime"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Исходящий вызов"
android:layout_marginTop="200dp"
android:textSize="@dimen/abc_dialog_padding_material"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/btncall"
android:layout_width="70dp"
android:layout_height="70dp"
android:layout_marginRight="50dp"
android:layout_marginBottom="50dp"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:background="@drawable/mybutton1"
/>
<Button
android:id="@+id/btnendcallCenter"
android:layout_width="70dp"
android:layout_height="70dp"
android:layout_marginBottom="50dp"
android:layout_centerHorizontal="true"
android:layout_alignParentBottom="true"
android:background="@drawable/endbutton"
/>
<Button
android:id="@+id/btnendcall"
android:layout_width="70dp"
android:layout_height="70dp"
android:layout_marginLeft="50dp"
android:layout_marginBottom="50dp"
android:layout_alignParentBottom="true"
android:background="@drawable/endbutton"
/>
</RelativeLayout>
код создания уведомления
using Android.App;
using Android.Content;
using Android.Graphics;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using AndroidX.Core.App;
using Corporate_messenger.Service;
using Corporate_messenger.Service.Notification;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Xamarin.Forms;
using AndroidApp = Android.App.Application;
[assembly: Dependency(typeof(Corporate_messenger.Droid.NotificationManager.NotificationCall))]
namespace Corporate_messenger.Droid.NotificationManager
{
class NotificationCall
{
const string channelId = "Call";
const string channelName = "Notification_Call";
const string channelDescription = "Вызовы";
public static string TitleKey = "Call_title";
public static string MessageKey = "Calll_message";
bool channelInitialized = false;
int pendingIntentId = 0;
Android.App.NotificationManager manager;
public event EventHandler NotificationReceived;
public static NotificationCall Instance { get; private set; }
public NotificationCall() => Initialize();
public void Initialize()
{
if (Instance == null)
{
CreateNotificationChannel();
Instance = this;
}
}
public void SendNotification(string title, string message)
{
if (!channelInitialized)
{
CreateNotificationChannel();
}
Show(title, message);
}
public void ReceiveNotification(string title, string message)
{
var args = new NotificationEventArgs()
{
Title = title,
Message = message,
};
NotificationReceived?.Invoke(null, args);
}
NotificationCompat.Builder notification;
public void Show(string title, string message)
{
Intent intent = new Intent(AndroidApp.Context, typeof(TcpCallActivity));
Intent IntentAcceptCall = new Intent("com.companyname.corporate_messenger.Accept_Receiver");
Intent intentCancelCall = new Intent("com.companyname.corporate_messenger.Cancel_Receiver");
intent.AddFlags(ActivityFlags.ClearTop);
SpecialData.UserCall = message;
TitleKey = "init_call";
intent.PutExtra(TitleKey, "init_call");
// intent.PutExtra(MessageKey, message);
var view = new RemoteViews("com.companyname.corporate_messenger", Resource.Layout.NotificationLayoutCall);
view.SetTextViewText(Resource.Id.title_user, message );
view.SetImageViewResource(Resource.Id.image, Resource.Drawable.kot);
PendingIntent pendingIntent = PendingIntent.GetActivity(AndroidApp.Context, pendingIntentId++, intent, PendingIntentFlags.UpdateCurrent);
PendingIntent pendingAcceptCall = PendingIntent.GetBroadcast(AndroidApp.Context, pendingIntentId++, IntentAcceptCall, PendingIntentFlags.UpdateCurrent);
PendingIntent pendingCancelCall = PendingIntent.GetBroadcast(AndroidApp.Context, pendingIntentId++, intentCancelCall, PendingIntentFlags.UpdateCurrent);
SpecialData.CallPageFlag = false;
view.SetOnClickPendingIntent(Resource.Id.button_accept_call, pendingAcceptCall);
view.SetOnClickPendingIntent(Resource.Id.button_stop_call, pendingCancelCall);
notification = new NotificationCompat.Builder(AndroidApp.Context, channelId)
.SetSmallIcon(Resource.Drawable.MyChat)
.SetAutoCancel(true)
.SetContentIntent(pendingIntent)
.SetPriority((int)NotificationPriority.Max)
.SetContent(view)
.SetContentTitle("Incoming call")
.SetFullScreenIntent(pendingIntent, true)
.SetOngoing(true)
.SetContentText(message);
Notification notif = notification.Build();
manager.Notify(0, notif);
SpecialData.managerCall = manager;
}
void CreateNotificationChannel()
{
manager = (Android.App.NotificationManager)AndroidApp.Context.GetSystemService(AndroidApp.NotificationService);
if (Build.VERSION.SdkInt >= BuildVersionCodes.O)
{
var channelNameJava = new Java.Lang.String(channelName);
var channel = new NotificationChannel(channelId, channelNameJava, NotificationImportance.Max)
{
LockscreenVisibility = NotificationVisibility.Public,
Importance = NotificationImportance.Max,
Description = channelDescription
};
manager.CreateNotificationChannel(channel);
}
channelInitialized = true;
}
long GetNotifyTime(DateTime notifyTime)
{
DateTime utcTime = TimeZoneInfo.ConvertTimeToUtc(notifyTime);
double epochDiff = (new DateTime(1970, 1, 1) - DateTime.MinValue).TotalSeconds;
long utcAlarmTime = utcTime.AddSeconds(-epochDiff).Ticks / 10000;
return utcAlarmTime; // milliseconds
}
}
}
Вот тут видно результат, кнопки не работают на samsung или huawei

Ответы (1 шт):
Если кому то будет интересно, проблема заключалось в том , что события нажатия я отслеживал через ресиверы почему то не на всех телефонах они регистрировались. В итоге я создал класс (Сервис)
namespace Corporate_messenger.Droid.NotificationManager.ActionNotification
{
[Service(Exported = true)]
class ActionAccept : IntentService
{
public ActionAccept()
{
//
}
protected override void OnHandleIntent(Intent intent)
{
switch (intent.Action) {
case "accept":
Task.Run(() => AcceptCall());
break;
case "drop":
Task.Run(() => DropCall());
break;
}
}
private async Task AcceptCall()
{
try
{
var user = await UserDbService.GetUser();
// Соеденияся
// DependencyService.Get<IAudioUDPSocketCall>().ConnectionToServer();
// отвечаем на звонок
SpecialData.MyWebSocket.Send(JsonConvert.SerializeObject(new
{
type = "init_call",
sender_id = user.Id,
status = "200",
receiver_id = SpecialData.receiver_id,
call_id = SpecialData.call_id
}));
// Запускаем tcp
SpecialData.CallPageFlag = true;
Intent mycallIntent = new Intent(Android.App.Application.Context, typeof(TcpCallActivity));
mycallIntent.AddFlags(ActivityFlags.NewTask);
Android.App.Application.Context.StartActivity(mycallIntent);
}
catch(Exception ex)
{
}
finally{
SpecialData.managerCall.Cancel(0);
DependencyService.Get<IAudio>().StopAudioFile();
}
}
AudioService audioService = new AudioService();
private async Task DropCall()
{
try
{
var MyUser = await UserDbService.GetUser();
SpecialData.MyWebSocket.Send(JsonConvert.SerializeObject(new { type = "close_call", status = "403", sender_id = MyUser.Id, call_id = SpecialData.call_id }));
}
catch(Exception ex)
{
}
finally
{
SpecialData.managerCall.Cancel(0);
audioService.StopAudioFile();
}
}
}
}
и при создании уведомления , я регистрировал две кнопки, привязанных к этому классу(сервису), но с разным Action, каждый раз при нажатии я попадал в этот класс, где проверял с каким Action он запустился. Вот отрывок кода.
Intent acceptIntent = new Intent(AndroidApp.Context, typeof(ActionAccept));
Intent dropIntent = new Intent(AndroidApp.Context, typeof(ActionAccept));
acceptIntent.SetAction("accept");
dropIntent.SetAction("drop");
view.SetOnClickPendingIntent(Resource.Id.button_stop_call, PendingIntent.GetService(AndroidApp.Context, 0, dropIntent, PendingIntentFlags.UpdateCurrent));
view.SetOnClickPendingIntent(Resource.Id.button_accept_call, PendingIntent.GetService(AndroidApp.Context, 0, acceptIntent, PendingIntentFlags.UpdateCurrent));
Вот полный код
[assembly: Dependency(typeof(Corporate_messenger.Droid.NotificationManager.NotificationCall))]
namespace Corporate_messenger.Droid.NotificationManager
{
class NotificationCall
{
const string channelId = "Call";
const string channelName = "Notification_Call";
const string channelDescription = "Вызовы";
public static string TitleKey = "Call_title";
public static string MessageKey = "Calll_message";
bool channelInitialized = false;
int pendingIntentId = 0;
Android.App.NotificationManager manager;
public event EventHandler NotificationReceived;
public static NotificationCall Instance { get; private set; }
public NotificationCall() => Initialize();
public void Initialize()
{
if (Instance == null)
{
CreateNotificationChannel();
Instance = this;
}
}
public void SendNotification(string title, string message)
{
if (!channelInitialized)
{
CreateNotificationChannel();
}
Show(title, message);
}
public void ReceiveNotification(string title, string message)
{
var args = new NotificationEventArgs()
{
Title = title,
Message = message,
};
NotificationReceived?.Invoke(null, args);
}
NotificationCompat.Builder notification;
Android.Widget.Button BtnStartCall;
Android.Widget.Button BtnEndCall;
public void Show(string title, string message)
{
Intent intent = new Intent(AndroidApp.Context, typeof(TcpCallActivity));
Intent IntentAcceptCall = new Intent("com.companyname.corporate_messenger.Accept_Receiver");
Intent intentCancelCall = new Intent("com.companyname.corporate_messenger.Cancel_Receiver");
intent.AddFlags(ActivityFlags.ClearTop);
SpecialData.UserCall = message;
TitleKey = "init_call";
intent.PutExtra(TitleKey, "init_call");
// intent.PutExtra(MessageKey, message);
var view = new RemoteViews("com.companyname.corporate_messenger", Resource.Layout.NotificationLayoutCall);
Intent acceptIntent = new Intent(AndroidApp.Context, typeof(ActionAccept));
Intent dropIntent = new Intent(AndroidApp.Context, typeof(ActionAccept));
acceptIntent.SetAction("accept");
dropIntent.SetAction("drop");
view.SetTextViewText(Resource.Id.title_user, message );
view.SetImageViewResource(Resource.Id.image, Resource.Drawable.kot);
PendingIntent pendingIntent = PendingIntent.GetActivity(AndroidApp.Context, pendingIntentId++, intent, PendingIntentFlags.UpdateCurrent);
SpecialData.CallPageFlag = false;
// view.SetOnClickPendingIntent(Resource.Id.button_accept_call, pendingAcceptCall);
// view.SetOnClickPendingIntent(Resource.Id.button_stop_call, pendingCancelCall);
view.SetOnClickPendingIntent(Resource.Id.button_stop_call, PendingIntent.GetService(AndroidApp.Context, 0, dropIntent, PendingIntentFlags.UpdateCurrent));
view.SetOnClickPendingIntent(Resource.Id.button_accept_call, PendingIntent.GetService(AndroidApp.Context, 0, acceptIntent, PendingIntentFlags.UpdateCurrent));
notification = new NotificationCompat.Builder(AndroidApp.Context, channelId)
.SetSmallIcon(Resource.Drawable.MyChat)
.SetAutoCancel(true)
.SetContentIntent(pendingIntent)
.SetPriority((int)NotificationPriority.Max)
.SetContent(view)
.SetContentTitle("Incoming call")
.SetFullScreenIntent(pendingIntent, true)
.SetOngoing(true)
.SetContentText(message)
.SetStyle(new NotificationCompat.DecoratedCustomViewStyle());
Notification notif = notification.Build();
manager.Notify(0, notif);
SpecialData.managerCall = manager;
}
void CreateNotificationChannel()
{
manager = (Android.App.NotificationManager)AndroidApp.Context.GetSystemService(AndroidApp.NotificationService);
if (Build.VERSION.SdkInt >= BuildVersionCodes.O)
{
var channelNameJava = new Java.Lang.String(channelName);
var channel = new NotificationChannel(channelId, channelNameJava, NotificationImportance.Max)
{
LockscreenVisibility = NotificationVisibility.Public,
Importance = NotificationImportance.Max,
Description = channelDescription
};
manager.CreateNotificationChannel(channel);
}
channelInitialized = true;
}
long GetNotifyTime(DateTime notifyTime)
{
DateTime utcTime = TimeZoneInfo.ConvertTimeToUtc(notifyTime);
double epochDiff = (new DateTime(1970, 1, 1) - DateTime.MinValue).TotalSeconds;
long utcAlarmTime = utcTime.AddSeconds(-epochDiff).Ticks / 10000;
return utcAlarmTime; // milliseconds
}
}
}