当前位置: 首页 > 知识库问答 >
问题:

如何在Xamarin表单中使用推送通知

谭伟
2023-03-14

我有一个使用Xamarin.Forms的应用程序,针对IOS,Android和WP 8。

我的应用中需要推送通知功能。

我看过<code>pushsharp</code>演示,它似乎很有前途。但我看到的所有代码都是针对每个平台分别编写的。

我希望这件事能在法庭上进行。Forms项目,在App.cs中的某个地方,这样我就不需要重复注册设备的代码,也不需要处理应该如何处理推送通知。

任何帮助都将不胜感激。欢迎使用示例代码或教程参考。

编辑:我根据Idot的答案实现了它。这是我答案的链接。

共有3个答案

倪灿
2023-03-14

在Xamarin表单中,您还可以使用通知SDK,如Donky(欧洲等同于美国城市飞艇);您可以在一天内轻松创建一个可扩展的通知项目,我使用此SDK在每次不到35分钟的时间内构建了两次WhatsApp克隆shell。看见http://docs.mobiledonky.com

东郭翰音
2023-03-14

xamarin support and forms建议我使用以下插件。

这个插件运行良好

https://github.com/rdelrosario/xamarin-plugins/tree/master/PushNotification

将更新答案,一旦我得到它的工作。

更新:

我得到了推送通知工作的iOS和Android。

我使用了Google Cloud Messaging Client,这是Android的一个出色组件,并且不必编写本答案中提到的大部分代码。

我的iOS实现与此类似,不需要太多代码。

为了从服务器推送通知,我使用了PushSharp的nuget包。

我没有在WP中实现,因为这在我的项目中不是必需的。

如果您打算实现推送通知,这篇关于推送通知的Xamarin帮助值得一读。

更新(2018年6月)-在iOS和Android上使用以下FCM插件,ti支持Xamarin。表单-FirebasePushNotificationPlugin

索令
2023-03-14

我几天前刚刚实现了推送通知,我将在这里分享我的解决方案(基于PushSharp)

逐步指南:

1)在您的共享项目中,创建一个名为< code > IPushNotificationRegister 的接口

public interface IPushNotificationRegister
{
    void ExtractTokenAndRegister();
}

该接口用于获取推送令牌,然后将其发送到服务器。该令牌在每个设备上都是唯一的。

2)在您的共享项目中,您应该调用ExtractTokenAndign(使用您最喜欢的IOC,我在登录后立即调用它)。

Android实现:

3) 添加用于收听Google GCM服务接收的事件的接收器:

a)

[BroadcastReceiver]
[IntentFilter(new[] { Intent.ActionBootCompleted })]
public class GCMBootReceiver : BroadcastReceiver
{
    public override void OnReceive(Context context, Intent intent)
    {
        MyIntentService.RunIntentInService(context, intent);
        SetResult(Result.Ok, null, null);
    }
}

(b)

[assembly: Permission(Name = "@PACKAGE_NAME@.permission.C2D_MESSAGE")]
[assembly: UsesPermission(Name = "android.permission.WAKE_LOCK")]
[assembly: UsesPermission(Name = "@PACKAGE_NAME@.permission.C2D_MESSAGE")]
[assembly: UsesPermission(Name = "com.google.android.c2dm.permission.RECEIVE")]
[assembly: UsesPermission(Name = "android.permission.GET_ACCOUNTS")]
[assembly: UsesPermission(Name = "android.permission.INTERNET")]

namespace Consumer.Mobile.Droid.PushNotification
{
    [BroadcastReceiver(Permission = "com.google.android.c2dm.permission.SEND")]
    [IntentFilter(new string[] { "com.google.android.c2dm.intent.RECEIVE" }, Categories = new string[] { "@PACKAGE_NAME@" })]
    [IntentFilter(new string[] { "com.google.android.c2dm.intent.REGISTRATION" }, Categories = new string[] { "@PACKAGE_NAME@" })]
    [IntentFilter(new string[] { "com.google.android.gcm.intent.RETRY" }, Categories = new string[] { "@PACKAGE_NAME@" })]
    [IntentFilter (new[]{ Intent.ActionBootCompleted }, Categories = new[]{ Intent.CategoryDefault })]
    public class GCMBroadcastReceiver : BroadcastReceiver
    {
        public override void OnReceive(Context context, Intent intent)
        {
            MyIntentService.RunIntentInService(context, intent);
            SetResult(Result.Ok, null, null);
        }
    }
}

c)添加Intent服务来处理通知

using Android.App;
using Android.Content;
using Android.Graphics;
using Android.Media;
using Android.OS;
using Android.Support.V4.App;
using Consumer.Mobile.Infra;
using Consumer.Mobile.Services.PushNotification;
using Java.Lang;
using XLabs.Ioc;
using TaskStackBuilder = Android.Support.V4.App.TaskStackBuilder;

namespace Consumer.Mobile.Droid.PushNotification
{
    [Service]
    public class MyIntentService : IntentService
    {
        private readonly ILogger _logger;
        private readonly IPushNotificationService _notificationService;
        private readonly IPushNotificationRegister _pushNotificationRegister;

        public MyIntentService()
        {
            _logger = Resolver.Resolve<ILogger>();
            _notificationService = Resolver.Resolve<IPushNotificationService>();
            _pushNotificationRegister = Resolver.Resolve<IPushNotificationRegister>();
        }

        static PowerManager.WakeLock _sWakeLock;
        static readonly object Lock = new object();


        public static void RunIntentInService(Context context, Intent intent)
        {
            lock (Lock)
            {
                if (_sWakeLock == null)
                {
                    // This is called from BroadcastReceiver, there is no init.
                    var pm = PowerManager.FromContext(context);
                    _sWakeLock = pm.NewWakeLock(
                    WakeLockFlags.Partial, "My WakeLock Tag");
                }
            }

            _sWakeLock.Acquire();
            intent.SetClass(context, typeof(MyIntentService));
            context.StartService(intent);
        }

        protected override void OnHandleIntent(Intent intent)
        {
            try
            {
                Context context = this.ApplicationContext;
                string action = intent.Action;

                if (action.Equals("com.google.android.c2dm.intent.REGISTRATION"))
                {
                    HandleRegistration(context, intent);
                }
                else if (action.Equals("com.google.android.c2dm.intent.RECEIVE"))
                {
                    HandleMessage(context, intent);
                }
            }
            finally
            {
                lock (Lock)
                {
                    //Sanity check for null as this is a public method
                    if (_sWakeLock != null)
                        _sWakeLock.Release();
                }
            }
        }

        private void HandleMessage(Context context, Intent intent)
        {

            Intent resultIntent = new Intent(this, typeof(MainActivity));


            TaskStackBuilder stackBuilder = TaskStackBuilder.Create(this);

            var c = Class.FromType(typeof(MainActivity));
            stackBuilder.AddParentStack(c);
            stackBuilder.AddNextIntent(resultIntent);

            string alert = intent.GetStringExtra("Alert");
            int number = intent.GetIntExtra("Badge", 0);

            var imageUrl = intent.GetStringExtra("ImageUrl");
            var title = intent.GetStringExtra("Title");

            Bitmap bitmap = GetBitmap(imageUrl);

            PendingIntent resultPendingIntent = stackBuilder.GetPendingIntent(0, (int)PendingIntentFlags.UpdateCurrent);

            NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
                .SetAutoCancel(true) // dismiss the notification from the notification area when the user clicks on it
                .SetContentIntent(resultPendingIntent) // start up this activity when the user clicks the intent.
                .SetContentTitle(title) // Set the title
                .SetNumber(number) // Display the count in the Content Info
                .SetSmallIcon(Resource.Drawable.Icon) // This is the icon to display
                .SetLargeIcon(bitmap)
                .SetSound(RingtoneManager.GetDefaultUri(RingtoneType.Notification))
                .SetContentText(alert); // the message to display.

            // Build the notification:
            Notification notification = builder.Build();

            // Get the notification manager:
            NotificationManager notificationManager =
                GetSystemService(Context.NotificationService) as NotificationManager;

            // Publish the notification:
            const int notificationId = 0;
            notificationManager.Notify(notificationId, notification);
        }

        private void HandleRegistration(Context context, Intent intent)
        {
            var token = intent.GetStringExtra("registration_id");
            _logger.Info(this.Class.SimpleName, "Received Token : " + token);

            if (_pushNotificationRegister.ShouldSendToken(token))
            {
                var uid = Android.Provider.Settings.Secure.GetString(MainActivity.Context.ContentResolver, Android.Provider.Settings.Secure.AndroidId);
                _notificationService.AddPushToken(token, DeviceUtils.GetDeviceType(), uid);
            }
        }


        private Bitmap GetBitmap(string url)
        {

            try
            {
                System.Net.WebRequest request =
                    System.Net.WebRequest.Create(url);
                System.Net.WebResponse response = request.GetResponse();
                System.IO.Stream responseStream =
                    response.GetResponseStream();
                return BitmapFactory.DecodeStream(responseStream);


            }
            catch (System.Net.WebException)
            {
                return null;
            }

        }

    }
}

d)实现接口< code > IPushNotificationRegister :

using Android.App;
using Android.Content;
using Consumer.Mobile.Services;
using Consumer.Mobile.Services.PushNotification;
[assembly: Permission(Name = "@PACKAGE_NAME@.permission.C2D_MESSAGE")]
[assembly: UsesPermission(Name = "@PACKAGE_NAME@.permission.C2D_MESSAGE")]

// Gives the app permission to register and receive messages.
[assembly: UsesPermission(Name = "com.google.android.c2dm.permission.RECEIVE")]

// Needed to keep the processor from sleeping when a message arrives
[assembly: UsesPermission(Name = "android.permission.WAKE_LOCK")]
[assembly: UsesPermission(Name = "android.permission.RECEIVE_BOOT_COMPLETED")]
namespace Consumer.Mobile.Droid.PushNotification
{
    public class PushNotificationRegister : IPushNotificationRegister
    {          
        public override void ExtractTokenAndRegister()
        {
            string senders = AndroidConfig.GCMSenderId;
            Intent intent = new Intent("com.google.android.c2dm.intent.REGISTER");
            intent.SetPackage("com.google.android.gsf");
            intent.PutExtra("app", PendingIntent.GetBroadcast(MainActivity.Context, 0, new Intent(), 0));
            intent.PutExtra("sender", senders);
            MainActivity.Context.StartService(intent);
        }


    }
}

iOS实施:

4) 在您的 AppDelegate 中,添加以下方法:

a)

public override void RegisteredForRemoteNotifications(UIApplication application, NSData deviceToken)
{
    var deviceTokenString = deviceToken.ToString().Replace("<","").Replace(">", "").Replace(" ", "");
    var notificationService = Resolver.Resolve<IPushNotificationService>();
    var pushNotificationRegister = Resolver.Resolve<IPushNotificationRegister>();

    if (pushNotificationRegister.ShouldSendToken(deviceTokenString))
    {
        var uid = UIDevice.CurrentDevice.IdentifierForVendor.AsString();
        notificationService.AddPushToken(deviceTokenString, DeviceUtils.GetDeviceType(), uid);
    }
}

b)实现< code > IPushNotificationRegister :

using Consumer.Mobile.Services;
using Consumer.Mobile.Services.PushNotification;
using UIKit;

namespace Consumer.Mobile.iOS.PushNotification
{
    public class iOSPushNotificationRegister : IPushNotificationRegister
    {
        public override void ExtractTokenAndRegister()
        {
            const UIRemoteNotificationType notificationTypes = UIRemoteNotificationType.Alert | UIRemoteNotificationType.Badge | UIRemoteNotificationType.Sound;
            UIApplication.SharedApplication.RegisterForRemoteNotificationTypes(notificationTypes);
        }
    }
}

关于WP,我没有实施。

如果您需要使用PushSharp在服务器端的代码,请告诉我。

您可以在这里查看我的解决方案所基于的客户端示例

 类似资料:
  • 我已经为我的Xamarin.Forms UWP应用程序实现了一个推送通知功能,我可以接收通知,然后弹出一个祝酒词。我正在使用下面的代码。 当用户单击/轻击通知时,我想从我的PCL项目中打开一个特定的页面,并将这个变量作为参数传递。我怎么能这么做?如有任何帮助,我们将不胜感激。

  • 我已经在我的应用程序上实现了推送通知,它们工作得很好。我遇到的问题是,当我点击下拉菜单中的它们时,它们会立即重新加载应用程序。为了解决这个问题,我让应用程序创建了一个新的活动实例。这现在打开了一个新的页面,但当点击从这个新的页面返回时,它有同样的问题,并重新加载整个应用程序。

  • full方法使用不同的方法,但值仍然不会传递给mainActivity。总是有一个空的?

  • 问题内容: 我一直在构建一个简单的应用程序来学习angular.js。到目前为止,我已经将MEAN堆栈中的所有内容连接在一起,并且能够从Mongo中保存和检索数据。 该应用程序本质上是一个待办事项列表。用户可以创建一个项目,并在项目内部创建带有“待办事项”的“卡片”,然后可以从一个州转移到另一个州(“积压”,“进行中”,“完成”等)。 我希望能够将通知推送给所有已连接的人员,以告知其应用程序需要刷

  • 我在Xamarin表单应用程序上使用推送通知时遇到图标徽章问题。我正在使用Firebase将应用程序发送到两台设备。 我让徽章在android上工作的方式是,该应用程序从有效负载的“数据”部分获取完整的通知信息。当通知只有一个数据部分时,我可以触发一个功能,设置徽章并显示弹出通知。如果我把相同的信息放在“通知”部分,我就不能触发设置徽章。 对于iOS,徽章计数从负载的通知部分发送。iOS看不到数据

  • 我们有一个HTML5网站,使用正常的用户登录和密码。我们已经将其封装在CodeCanyon上购买的WebView应用程序中。该应用程序有一个功能的推送通知,这是配置和工作良好。 我们想发送用户特定的推送通知。在OneSignal中,我们可以看到设备ID,但我们没有得到用户ID。在我们的网站数据库中,我们只能看到用户ID。 我们理解,需要一些编程来链接这一点。我们需要帮助实现以下目标: a)当用户从