使用Xamarin.Forms和Azure推送通知:设备未注册

时间:2018-09-25 23:06:17

标签: android azure xamarin.forms push-notification

我逐步遵循了以下教程: https://docs.microsoft.com/it-it/azure/notification-hubs/xamarin-notification-hubs-push-notifications-android-gcm

我在装有Android 8.0.0的物理设备上启动了Android应用程序。然后还要在3个仿真器(API 23、25和27)上进行。

在Azure控制面板中,注册的设备始终为零。结果,发送测试成功,但是没有通知到达设备(“ 消息已成功发送,但是没有匹配的目标”)。

我跳过了有关设备注册的几个步骤?

*代码集成* *** [起始代码]

MainActivity.cs

namespace test021_push.Droid
{
    [Activity(Label = "test021_push", Icon = "@mipmap/icon", Theme = "@style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
    public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
    {
        public const string TAG = "MainActivity";

        protected override void OnCreate(Bundle savedInstanceState)
        {
            TabLayoutResource = Resource.Layout.Tabbar;
            ToolbarResource = Resource.Layout.Toolbar;

            base.OnCreate(savedInstanceState);

            //push notification
            if (Intent.Extras != null)
            {
                foreach (var key in Intent.Extras.KeySet())
                {
                    if (key != null)
                    {
                        var value = Intent.Extras.GetString(key);
                        Log.Debug(TAG, "Key: {0} Value: {1}", key, value);
                    }
                }
            }

            global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
            LoadApplication(new App());
        }
    }
}

Constants.cs

namespace test021_push.Droid
{
    public static class Constants
    {
        public const string ListenConnectionString = "Endpoint=sb://namespacepodo.servicebus.windows.net/;SharedAccessKeyName=DefaultListenSharedAccessSignature;SharedAccessKey=lN8fZnQYlYQ/ELVrgnzUD16MBw9bOTH/Yxaw2LANA58=";
        public const string NotificationHubName = "notificationHubPodo";
    }
}

MyFirebaseIIDService.cs

namespace test021_push.Droid
{
    [Service]
    [IntentFilter(new[] { "com.google.firebase.INSTANCE_ID_EVENT" })]
    public class MyFirebaseIIDService : FirebaseInstanceIdService
    {
        const string TAG = "MyFirebaseIIDService";
        NotificationHub hub;

        public override void OnTokenRefresh()
        {
            var refreshedToken = FirebaseInstanceId.Instance.Token;
            Log.Debug(TAG, "FCM token: " + refreshedToken);
            SendRegistrationToServer(refreshedToken);
        }

        void SendRegistrationToServer(string token)
        {
            // Register with Notification Hubs
            hub = new NotificationHub(Constants.NotificationHubName, Constants.ListenConnectionString, this);

            var tags = new List<string>() { };
            var regID = hub.Register(token, tags.ToArray()).RegistrationId;

            Log.Debug(TAG, $"Successful registration of ID {regID}");
        }
    }
}

MyFirebaseMessagingService.cs

namespace test021_push.Droid
{
    [Service]
    [IntentFilter(new[] { "com.google.firebase.MESSAGING_EVENT" })]
    public class MyFirebaseMessagingService : FirebaseMessagingService
    {
        const string TAG = "MyFirebaseMsgService";
        public override void OnMessageReceived(RemoteMessage message)
        {
            Log.Debug(TAG, "From: " + message.From);
            if (message.GetNotification() != null)
            {
                //These is how most messages will be received
                Log.Debug(TAG, "Notification Message Body: " + message.GetNotification().Body);
                SendNotification(message.GetNotification().Body);
            }
            else
            {
                //Only used for debugging payloads sent from the Azure portal
                SendNotification(message.Data.Values.First());

            }

        }

        void SendNotification(string messageBody)
        {
            var intent = new Intent(this, typeof(MainActivity));
            intent.AddFlags(ActivityFlags.ClearTop);
            var pendingIntent = PendingIntent.GetActivity(this, 0, intent, PendingIntentFlags.OneShot);

            //var notificationBuilder = new Notification.Builder(this)  //Notification.Builder è deprecato
            var notificationBuilder = new NotificationCompat.Builder(this)
                        .SetContentTitle("FCM Message")
                        .SetSmallIcon(Resource.Drawable.ic_launcher)
                        .SetContentText(messageBody)
                        .SetAutoCancel(true)
                        .SetContentIntent(pendingIntent);

            var notificationManager = NotificationManager.FromContext(this);

            notificationManager.Notify(0, notificationBuilder.Build());
        }
    }
}

*** [结束代码]

现在,通知仅在设备(模拟器Android API 25)上到达。在其他仿真器(API 23和27)以及物理设备中,什么也没有发生。尽管在所有4种设备上都执行了完全相同的过程。

在Azure上,我看到3个注册的设备。

非常感谢您的回答。

1 个答案:

答案 0 :(得分:0)

您是否已在Firebase控制台中检查是否正在注册设备?

还要在启动应用程序时检查日志。 在Firebase上注册可能会失败。 只需在日志中搜索“ firebase”即可。 另外尝试在OnTokenRefresh()

中添加一个断点

如果失败,则可能是您的google-services.json错误或构建操作错误。

编辑:Azure文档已过时。 Android 8.0添加了“通知频道”功能。并且您必须使用它,否则将不会显示通知。但是,此操作仅修复了显示通知的问题。如果通知未在OnMessageReceived(RemoteMessage message)到达,则存在另一个错误。

我在SendNotification方法中解决了这个问题

        var channelId = "testChannelId";
        var channelDescription = "Test Description";

        var builder = Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.O
            ? new Notification.Builder(Android.App.Application.Context, channelId)
            : new Notification.Builder(Android.App.Application.Context);

        var notification = builder
                    .SetContentTitle("Test")
                    .SetContentText(messageBody)
                    .SetSmallIcon(Resource.Drawable.ic_notification)
                    .SetAutoCancel(true)
                    .SetWhen(DateTime.Now.ToUnixMillisecondTime())
                    .SetShowWhen(true)
                    .Build();
        var notificationManager = NotificationManager.FromContext(Application.Context);

        if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.O)
        {
            var channel = new NotificationChannel(channelId,
                    channelDescription,
                    NotificationImportance.Default);
            notificationManager.CreateNotificationChannel(channel);
        }