xamarin - 如何从推送通知中取消注册客户端?

标签 xamarin xamarin.android google-cloud-messaging xamarin.forms

我正在使用 Azure 通知中心和 Androud GCM 开发 Xamarin.Forms 应用。现在,当我的用户注册时,我将他注册到通知中:

我有一个界面:

public interface IPushNotificationService
    {
        void Register();
        void UnRegister();
    }

在 Android 项目中,我将接口(interface)实现为:

public class PushNotificationService : IPushNotificationService
    {

        public PushNotificationService() { }

        public void Register()
        {
            RegisterWithGCM();
        }

        public void UnRegister()
        {
            try
            {
                GcmClient.UnRegister(MainActivity.instance);
            }
            catch (Exception e)
            {
                Log.Verbose(PushHandlerBroadcastReceiver.TAG, "ERROR while UnRegistering - " + e.Message);
            }

        }

        private void RegisterWithGCM()
        {
            try
            {
                // Check to ensure everything's setup right
                GcmClient.CheckDevice(MainActivity.instance);
                GcmClient.CheckManifest(MainActivity.instance);

                // Register for push notifications
                UnRegister();
                Log.Verbose(PushHandlerBroadcastReceiver.TAG, "Registering...");
                GcmClient.Register(MainActivity.instance, Constants.SenderID);
            }
            catch (Java.Net.MalformedURLException)
            {
                Log.Verbose(PushHandlerBroadcastReceiver.TAG, "ERROR - There was an error creating the client. Verify the URL.");
            }
            catch (Exception e)
            {
                Log.Verbose(PushHandlerBroadcastReceiver.TAG, "ERROR - " + e.Message);
                CreateAndShowDialog("Cannot register to push notification. Please try to run the app again.", "Error");
            }
        }

        private void CreateAndShowDialog(String message, String title)
        {
            AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.instance);

            builder.SetMessage(message);
            builder.SetTitle(title);
            builder.Create().Show();
        }
    }

我还在 Azure MSDN 站点中监听了 GcmService:

[assembly: Permission(Name = "@<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="6f3f2e2c242e282a30212e222a2f411f0a1d02061c1c060001412c5d2b" rel="noreferrer noopener nofollow">[email protected]</a>_MESSAGE")]
[assembly: UsesPermission(Name = "@<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="8adacbc9c1cbcdcfd5c4cbc7cfcaa4faeff8e7e3f9f9e3e5e4a4c9b8ce" rel="noreferrer noopener nofollow">[email protected]</a>_MESSAGE")]
[assembly: UsesPermission(Name = "com.google.android.c2dm.permission.RECEIVE")]
[assembly: UsesPermission(Name = "android.permission.INTERNET")]
[assembly: UsesPermission(Name = "android.permission.WAKE_LOCK")]
namespace MyApp.Droid
{
    [BroadcastReceiver(Permission = Gcm.Client.Constants.PERMISSION_GCM_INTENTS)]
    [IntentFilter(new string[] { Gcm.Client.Constants.INTENT_FROM_GCM_MESSAGE }, Categories = new string[] { "@PACKAGE_NAME@" })]
    [IntentFilter(new string[] { Gcm.Client.Constants.INTENT_FROM_GCM_REGISTRATION_CALLBACK }, Categories = new string[] { "@PACKAGE_NAME@" })]
    [IntentFilter(new string[] { Gcm.Client.Constants.INTENT_FROM_GCM_LIBRARY_RETRY }, Categories = new string[] { "@PACKAGE_NAME@" })]
    public class PushHandlerBroadcastReceiver : GcmBroadcastReceiverBase<GcmService>
    {
        public static string[] SENDER_IDS = new string[] { "XXXXX" };
        public static string TAG = "PUSH_NOTIFICATIONS";
    }

    [Service]
    public class GcmService : GcmServiceBase
    {
        public static string RegistrationID { get; private set; }
        private NotificationHub Hub { get; set; }

        public GcmService()
            : base(PushHandlerBroadcastReceiver.SENDER_IDS) { }

        protected override void OnRegistered(Context context, string registrationId)
        {
            Log.Verbose(PushHandlerBroadcastReceiver.TAG, "GCM Registered: " + registrationId);
            RegistrationID = registrationId;

            Hub = new NotificationHub(Constants.NotificationHubName, Constants.ListenConnectionString,
                                 context);
            try
            {
                Hub.UnregisterAll(registrationId);
                Hub.Unregister();
            }
            catch (Exception ex)
            {
                Log.Error(PushHandlerBroadcastReceiver.TAG, ex.Message);
            }

            var userId = Settings.UserId;
            if (! String.IsNullOrWhiteSpace(userId))
            {
                Log.Verbose(PushHandlerBroadcastReceiver.TAG, "Registering user_id: " + userId);

                var tags = new List<string>() { userId };

                try
                {
                    Hub.Register(registrationId, tags.ToArray());
                }
                catch (Exception ex)
                {
                    Log.Error(PushHandlerBroadcastReceiver.TAG, ex.Message);
                }
            }
        }

        protected override void OnMessage(Context context, Intent intent)
        {
            Log.Info(PushHandlerBroadcastReceiver.TAG, "GCM Message Received!");

            var msg = new StringBuilder();

            if (intent != null && intent.Extras != null)
            {
                foreach (var key in intent.Extras.KeySet())
                    msg.AppendLine(key + "=" + intent.Extras.Get(key).ToString());
            }

            string message = intent.Extras.GetString("message");
            if (!string.IsNullOrEmpty(message))
            {
                createNotification("New Message", message);
                return;
            }

            Log.Error(PushHandlerBroadcastReceiver.TAG, "Unknown message details: " + msg);
        }

        void createNotification(string title, string desc)
        {
            //Create notification
            var notificationManager = GetSystemService(Context.NotificationService) as NotificationManager;

            //Create an intent to show ui
            var uiIntent = new Intent(this, typeof(MainActivity));

            //Use Notification Builder
            NotificationCompat.Builder builder = new NotificationCompat.Builder(this);

            //Create the notification
            //we use the pending intent, passing our ui intent over which will get called
            //when the notification is tapped.


            var notification = builder.SetContentIntent(PendingIntent.GetActivity(this, 0, uiIntent, 0))
                    .SetSmallIcon(Resource.Drawable.ic_stat_ic_notification)
                    .SetTicker(title)
                    .SetContentTitle(title)
                    .SetContentText(desc)
                    //.AddAction(new NotificationCompat.Action())


                    //Set the notification sound
                    .SetSound(RingtoneManager.GetDefaultUri(RingtoneType.Notification))

                    //Auto cancel will remove the notification once the user touches it
                    .SetAutoCancel(true).Build();

            //Show the notification
            notificationManager.Notify(1, notification);
        }

        protected override void OnUnRegistered(Context context, string registrationId)
        {
            Log.Info(PushHandlerBroadcastReceiver.TAG, "Unregistered RegisterationId : " + registrationId);

            try
            {
                Hub = new NotificationHub(Constants.NotificationHubName, Constants.ListenConnectionString,
                                 context);

                Hub.Unregister();

                if (!String.IsNullOrWhiteSpace(registrationId))
                    Hub.UnregisterAll(registrationId);
            }
            catch (Exception e)
            {
                Log.Error(PushHandlerBroadcastReceiver.TAG, "Error while unregistering: " + e.Message);
            }
        }

        protected override void OnError(Context context, string errorId)
        {
            Log.Error(PushHandlerBroadcastReceiver.TAG, "GCM Error: " + errorId);
        }
    }
}

现在,当用户登录到我调用的应用程序时:

DependencyService.Get<IPushNotificationService>().Register();

当他注销时,我打电话:

现在,当用户登录到我调用的应用程序时:

DependencyService.Get<IPushNotificationService>().UnRegister();

我在这里做错了什么?当用户注销时,我在调试中看到调用了所有 Unregister 方法,但用户仍然收到新消息。

谢谢, 赛义夫。

最佳答案

也许问题出在:

Hub = new NotificationHub(Constants.NotificationHubName, Constants.ListenConnectionString,
                             context);

您正在创建 NotificationHub 的新对象,该对象可能未引用初始连接。

您可以尝试创建一个字段NotificationHub _hub;在注册步骤中设置其值;并在取消注册步骤中使用此字段:

            _hub.Unregister();

            if (!string.IsNullOrWhiteSpace(registrationId))
                _hub.UnregisterAll(registrationId);

免责声明:没有尝试此解决方案。希望对您有所帮助。

关于xamarin - 如何从推送通知中取消注册客户端?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41040933/

相关文章:

android - 收到 GCM 消息时,静态对象并不总是存在

c# - Visual Studio Xamarin 模板缺少程序集引用

Node.js 向 GCM 服务器发送消息

c# - Xamarin 表单 XAML : How can I inherit properties from another XAML file like ResourceDictionaries?

xamarin.forms - 错误 :Xamarin. 表单目标已多次导入

c# - xamarin - ImageView 在从画廊的相机拍摄照片后显示黑色图像

c# - Xamarin Android Visualizer SetDataCaptureListener 抛出 InvalidCastException

android - 收到的 GCM 消息显示为乱码

android - Xamarin - Shell.Current.GoToAsync 和后退按钮

c# - 如何禁止在 uipopovercontroller 后面的 View 上进行交互