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

时间:2016-12-08 13:42:01

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

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

我有一个界面:

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

在Android项目中,我将界面实现为:

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 = "@PACKAGE_NAME@.permission.C2D_MESSAGE")]
[assembly: UsesPermission(Name = "@PACKAGE_NAME@.permission.C2D_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方法都被调用但用户仍然收到新消息。

谢谢, 赛福

1 个答案:

答案 0 :(得分:2)

也许问题在于:

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

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

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

            _hub.Unregister();

            if (!string.IsNullOrWhiteSpace(registrationId))
                _hub.UnregisterAll(registrationId);
免责声明:没试过这个解决方案。希望它有所帮助。