How can I check if push notifications are enabled on the device on iOS/Android?

Kim Strasser 1,321 Reputation points
2023-02-19T09:10:15.4266667+00:00

I want to display in my application's menu if push notifications are enabled or not on the device. How can I check if push notifications are enabled when the user opens the menu in my iOS/Android application?

In addition, is it possible to display the push notifications permission dialog again on iOS/Android after the user has already chosen don't allow when he started my app the first time or should I just tell the user in my menu that he should go to the settings of his device and then enable push notifications in my application's informations?

In an old thread on stackoverflow I have read that it is not possible to display the permission dialog again on iOS after the user has chosen don't allow. Is this still true on current iOS versions?

Developer technologies | .NET | .NET MAUI
0 comments No comments
{count} votes

Accepted answer
  1. Wenyan Zhang (Shanghai Wicresoft Co,.Ltd.) 36,436 Reputation points Microsoft External Staff
    2023-02-20T08:57:09.2+00:00

    Hello,

    You can determine whether the push notifications permission is enabled or not.

    is it possible to display the push notifications permission dialog again

    No. If the user doesn't allow the permission, you cannot display the system pop-up by code. As a solution, you can prompt the user to go to Settings page on the device to open notifications permission.

    For .net-ios Project
    In FinishedLaunching method

    Since I'm not sure how you set the game page/viewcontroller and if the RootViewController has been set, you can try to add the following code after RunGame() method.

     UNUserNotificationCenter.Current.GetNotificationSettings((settings) =>
            {
                if (settings.AuthorizationStatus == UNAuthorizationStatus.NotDetermined || settings.AuthorizationStatus == UNAuthorizationStatus.Denied)
                {
                    InvokeOnMainThread(() =>// in UI thread
                    {
                        var okAlertController = UIAlertController.Create("Title", "go to setting", UIAlertControllerStyle.Alert);
    
                        //Add Action
                        okAlertController.AddAction(UIAlertAction.Create("OK", UIAlertActionStyle.Default, (e) =>
                        {
                            var nurl = NSUrl.FromString(UIApplication.OpenNotificationSettingsUrl);
                            UIApplication.SharedApplication.OpenUrl(nurl!, new NSDictionary(), null); // This line of code will make app go to Notification page. If you test on simulator, the app will jump to Settings page.
                        }));
    
                        okAlertController.AddAction(UIAlertAction.Create("Cancle", UIAlertActionStyle.Cancel, null));
                        UIApplication.SharedApplication.Delegate.GetWindow().RootViewController!.PresentViewController(okAlertController, true, null);//window.RootViewController might be null
                    });
                }
                else
                {
                }
            });
    

    Or you can determine whether the push notifications permission is enabled or no in the ViewWillAppear method of your ViewController.(There is no ViewController on your screenshot, I'm not sure if there is a custom controller in your app)

    public override void ViewWillAppear(bool animated)
        {
            base.ViewWillAppear(animated);
            UNUserNotificationCenter.Current.GetNotificationSettings((settings) => {...
                
            });
        }
    

    Update

    I get an error when I want to use the code in my shared code project(Error CS0103: The name 'InvokeOnMainThread' does not exist in the current context)

    NSObject.InvokeOnMainThread is a native iOS method, and it can be called in the FinishedLaunching method.   MainThread.BeginInvokeOnMainThread is a .net method and can be used in your MAUI project (Both shared project and under Platform/iOS).

    I have tried to remove 'InvokeOnMainThread' but then I get this exception:

    The DisplayAlert method and going to Settings method are only allowed in Main/UI thread, you cannot remove it.

    'UIApplication.OpenNotificationSettingsUrl' is only supported on: 'ios' 15.4 and later, 'maccatalyst' 15.4 and later, 'tvos' 15.4 and later.

    OpenNotificationSettingsUrl is available on iOS15.4 and above and it will make app go to Notifications page of Settings. You can use OpenSettingsUrlString (it will make app go to Settings page) before iOS15.4 system, and use OpenNotificationSettingsUrl after: var SettingsString = UIDevice.CurrentDevice.CheckSystemVersion(15, 4) ? UIApplication.OpenNotificationSettingsUrl : UIApplication.OpenSettingsUrlString;

    In Program.cs, I don't get the error 'InvokeOnMainThread' but I always get an exception when I use the code in public override void FinishedLaunching:

    It means that RootViewController is null. I'm not sure how you set you set the MainPage in your project. In the previous comment, you said it crashed at this line (bool isAllow = await App.Current.MainPage.DisplayAlert("Alert", "go to setting","Yes","No"); ), you can check if there is not a MainPage, then show the alert on the same page where the button is.

    For MAUI project and invoking platform code

    PushNotificationService.cs

     public partial class PushNotificationService
          {
            public partial void CheckNotificationPermission(Action action);
        }
    

    PushNotificationService.ios.cs

     public partial void CheckNotificationPermission(Action action) {
    
                UNUserNotificationCenter.Current.GetNotificationSettings( (settings) => {
                    if (settings.AuthorizationStatus == UNAuthorizationStatus.NotDetermined || settings.AuthorizationStatus == UNAuthorizationStatus.Denied)
                    {
                        action();}
                    else{
                    }
                });
            }
    

    ButtonClickMethod(pay attention to the namespace #if IOSusing UIKit;#endif )

    private void OnCounterClicked(object sender, EventArgs e)
          {
    #if IOS
    
        PushNotificationService pushNotificationService = new PushNotificationService();
    
                pushNotificationService.CheckNotificationPermission( () =>  {
                      MainThread.BeginInvokeOnMainThread(async () =>
                      {
    
                bool isAllow = await DisplayAlert("Alert", "go to setting", "Yes", "No");
                if (isAllow)
                {
                    var SettingsString = UIDevice.CurrentDevice.CheckSystemVersion(15, 4) ? UIApplication.OpenNotificationSettingsUrl : UIApplication.OpenSettingsUrlString;
                    var nurl = NSUrl.FromString(SettingsString);
                    UIApplication.SharedApplication.OpenUrl(nurl!, new NSDictionary(), null);
                }
            });
    
                });
    #endif
    
    }
    

    Best Regards,

    Wenyan Zhang


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.