OnNavigatedFrom is not called when the app is suspended - c#

Today I've encountered strange problem - seems that on my device (v. 8.10.14203.306) OnNavigatedFrom event is not getting called when the app is being suspended. As far as I remember some time ago it was working ok, and exacly as documentation stays:
Note On Windows Phone, OnNavigatedFrom() is called when the app is suspended. OnNavigatedTo() is not called when the app is resumed.
I've tried a simple example (available at GitHub):
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
this.navigationHelper.OnNavigatedFrom(e);
Debug.WriteLine("Navigation");
this.Background = new SolidColorBrush(Colors.Red);
}
when there is normal navigation (e.g. by back button) the event is fired, but no more when the app is suspended - both in debug and release mode. I've also checked if the Suspending event is fired and it turnes out that it is:
// uncomment this to check if app is being suspended
App.Current.Suspending += (sender, e) => this.Background = new SolidColorBrush(Colors.Blue);
Am I missing something?

The only thing I can suggest is to make sure that you're calling Frame.GetNavigationState from within your Application.Suspending handler (this is usually done by SuspensionManager.SaveAsync). According to the docs:
Calling this method will call Page.OnNavigatedFrom for the current page using NavigationMode.Forward. GetNavigationState is usually called when the application is being suspended, so the current page is navigated away from.

Related

UWP Page.OnNavigatedFrom() not called when app is terminated

I've overridden the Page.OnNavigatedFrom() method in a UWP app. The method is called when I navigate to another Page. According to the documentation, Page.OnNavigatedFrom() is:
Invoked immediately after the Page is unloaded and is no longer the
current source of a parent Frame.
However, when I terminate the app, the Page's OnNavigatedFrom() is not called. Shouldn't terminating the app unload the Page?
// Not called when app is terminated
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
base.OnNavigatedFrom(e);
}
Update
I appreciate the comments. To be more clear, I should have said that I was closing the app, not terminating the app. (Closing the app first suspends and then terminates the app.) I discovered that putting a call to Frame.GetNavigationState() in OnSuspending() caused OnNavigatedFrom() to be called even when the user closes the app:
private void OnSuspending(object sender, SuspendingEventArgs e)
{
var deferral = e.SuspendingOperation.GetDeferral();
//TODO: Save application state and stop any background activity
// Triggers currently loaded Page's OnNavigatedFrom
Frame frame = Window.Current.Content as Frame;
ApplicationData.Current.LocalSettings.Values["NavigationState"] =
frame.GetNavigationState();
deferral.Complete();
}
Invoked immediately after the Page is unloaded and is no longer the current source of a parent Frame
I think you misunderstood the document. OnNavigatedFrom() method will invoked when page unloaded and is no longer the current source of frame. It is page life cycle only available in the scenario of navigation stack.
But, terminate is the app life cycle concept. and its priority is higher than the page life cycle.
When you terminate uwp app, OnSuspending event handler will be invoked, if you want to save page data, you could subscribe this event in page class.

UWP c# app with two kinds of onActivated listeners available - Activation by notification

Currently in my apps i am registering an onActivated listener to be executed and checked for my sharing activity like so:
Window.Current.Activated += Current_Activated;
with the method as follows to check for the activation state:
private async void Current_Activated(object sender, Windows.UI.Core.WindowActivatedEventArgs e)
{
if (e.WindowActivationState == CoreWindowActivationState.Deactivated)
{
}
else
{} }
Now i would like to implement an activation from a notification from a background task. The click on the notification is currently opening the app or brings it to the foreground if already open. This is standard behaviour. Now I would like to execute some code on activation by the notification but my method never gets called and I am not completely understanding Microsofts online material as it seems relatively simple.
I am registering the listener as such:
(Application.Current as App).Activated = new EventHandler<IActivatedEventArgs>(App_Activated);
and the method that never gets called looks like this:
private void App_Activated(object sender, IActivatedEventArgs e)
{ }
Are those two conflicting each other? is there something I can do to implement the notification activation into my existing method?
I've read through this and many more pages: https://blogs.msdn.microsoft.com/tiles_and_toasts/2015/07/08/quickstart-sending-a-local-toast-notification-and-handling-activations-from-it-windows-10/
Even from a test app i downloaded i don't really understand what needs to be done. Besides that i don't need to pass any info from the notification to the main activity. Simply just open it and execute one command of refreshing the page, but only on notification activation.
You should just override the OnActivated(IActivatedEventArgs args) method in your App.xaml.cs and check whether the args.Kind property is ActivationKind.ToastNotification.
You can find more info about handling an UWP app activation here.
As Marian said, you need to override the OnActivated method in your App.xaml.cs class. The OnActivated method is called when your toast is clicked, and it contains the toast arguments, so that you know what toast was clicked. Note that you must perform the same Frame initialization in your OnActivated as you do your OnLaunched, since if the user clicks on a toast while your app is closed, only the OnActivated method will be called - the OnLaunched won't be called.
This Quickstart explains exactly how to handle toast activation, and includes a full code sample: Quickstart: Sending a local Toast notification

AppBarButton exception in Universal WinRT app not triggering unhandled exception event

I have a Universal WinRT app and I'm trying to implement global exception handling so I can prompt the user to send me a report with extra diagnostic information I've collected. (The extra diagnostic information is why I can't use the built-in handler that will log up to the Dev Portal).
I have the following code:
public App() {
InitializeComponent();
UnhandledException += OnUnhandledException;
// other stuff
}
private void OnUnhandledException(object sender, UnhandledExceptionEventArgs e) {
try {
//handler
}
catch { }
throw e.Exception;
}
When I force an exception in my initial XAML page (my sign in page), e. g. hard code
throw new FileNotFoundException();
then my handler is triggered as expected. However, if I do this in my main hub page, which my start page navigates to, then it looks like my handler doesn't run. I can see the exception being thrown in the debugger, but it just gets swallowed somewhere. I can't find out where. I should mention that the app happily continues on at this point - it doesn't crash.
I've set DISABLE_XAML_GENERATED_BINDING_DEBUG_OUTPUT and DISABLE_XAML_GENERATED_BREAK_ON_UNHANDLED_EXCEPTION in my Project Properties to disable the built-in overrides, and as far as I know there's no async void situation here (e. g. Unhandled exception handler not called for Metro / WinRT UI async void event handler - although from what I've read, that kind of issue is resolved in 8.1 in any event). But there may be some kind of hidden async void thing going on that I'm not seeing.
I'm sure I'm missing something stupid. What is it?
(EDIT) It appears this is an issue when the exception is in a AppBarButton button event specifically.
(EDIT 2) A somewhat minimum repro is here: http://1drv.ms/1rSNq3i - run this in the 8.1 emulator or on an 8.1 phone, tap the button, open the commandbar, and choose sign out - this should trigger an exception and the handler, but the exception is lost. If you move the code to a button in the same page (a standard button), the handler fires.
(EDIT 3) I tried using the dispatcher in a minimal way, and it didn't change the visible result:
private void SignOutAppBarButton_Click(object sender, RoutedEventArgs e) {
Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => {
throw new FileNotFoundException();
}).AsTask().Wait();
}
In addition to the UnhandledException event you need to handle Frame.NavigationFailed. An exception in a page constructor results in firing NavigationFailed.

How can i override back button as I used to?

I've just installed Windows Phone 8.1 SDK, and had an application in mind. But I cant even navigate back and forth! Back button the phone exit the application by default, and since all the pages now inherits "Page" the override for the back button isnt exposed.
Read http://msdn.microsoft.com/en-us/library/windows/apps/xaml/dn639128.aspx but I don't understand it, how can I implement it?
Take a look at any of the WP Projects that are included with Visual Studio (eg: The Hub App project). Or add a new "BasicPage" to your application. You will notice that they are using a NAvigationHelper to subscribe to the BackPressed event for you already. The post you linked to explains it pretty well.
The most important thing to know about the BackPressed event that is raised when the user presses the back button is that if your app does not handle the event, by setting BackPressedEventArgs.Handled property to true, the operating system will suspend your app and return the user to the previous experience
The example is given in that post
private void HardwareButtons_BackPressed(object sender, BackPressedEventArgs e)
{
Frame frame = Window.Current.Content as Frame;
if (frame == null)
{
return;
}
if (frame.CanGoBack)
{
frame.GoBack();
e.Handled = true;
}
}
Notice it sets e.Handled = true; to indicate that the app should not "close". You are saying "Hey, I've got this handled already". In the example, it will navigate to the previous page.

Capture Activated event for an App

I am referring to http://msdn.microsoft.com/en-us/library/windows/apps/hh464925.aspx#app_activation
// App is an Application
public App()
{
this.InitializeComponent();
// Doesn't compile
//this.Activated += OnActivated;
this.Suspending += OnSuspending;
}
protected override void OnActivated(IActivatedEventArgs args)
{
System.Diagnostics.Debug.WriteLine("OnActivated");
}
private void OnSuspending(object sender, SuspendingEventArgs e)
{
var deferral = e.SuspendingOperation.GetDeferral();
deferral.Complete();
}
Note, OnActivated will never be triggered. OnSuspending will be triggered, after I quit the app around 30 seconds.
How can I capture Activated event? It is weird that I do not find Activated event in App, although the documentation says so.
The activation is a little confusing. Take a look at the documentation here:
http://msdn.microsoft.com/en-us/library/windows/apps/br242324.aspx
What you'll find is that when the user taps the tile, only the OnLaunched event is fired (see documentation here: http://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.xaml.application.onactivated.aspx )
The OnActivated is only for special cases outside of the ordinary launch. That would be any one of the following:
OnFileActivated
OnSearchActivated
OnShareTargetActivated
OnFileOpenPickerActivated
OnFileSavePickerActivated
OnCachedFileUpdaterActivated
So if you truly want something that is called anytime the app is activated regardless of how, I'd suggest making your own private method, then calling it from both OnLaunched and OnActivated. That should hit all cases for activation.
Maybe the problem is that you launch the app normally for example, by tapping the app tile(without facts, I'm just guessing). In this case, only the OnLaunched method is called.
msdn

Categories