MediaElement doesn't play back after restored from TombStoning - windows-phone-7

I have a MediaElement that I use for playing a music across pages. Hence, I had to keep it as a resource in App.xaml.
Things works as expected until I press the Windows Button in my WP. The application gets tombstoned, and MediaElement stops playing as expected. On my Application_Deactivated, I explicitly call Player.Stop()
The issue happens when I restore the application. All the other state is restored, but the mediaelement doesn't play the music. I can see that the code responsible for music is getting hit, but MediaElement's MediaOpened is not fired. Am I missing something obvious?
EDIT [to clarify KeyboardP's question]
<Application.Resources>
<MediaElement x:Name="ME" MediaEnded="RepeatMedia" Volume="1" AutoPlay="False" Height="0" Source="/Sounds/mywave.wav" />
</Application.Resources>
In my App.XAML.CS, I have a method called...
public MediaElement player = null;
private void InitializeMusic()
{
if (App.Current.Resources.Contains("ME"))
{
player = App.Current.Resources["ME"] as MediaElement;
}
player.MediaOpened += player_MediaOpened;
}
I am initializing it again in...
// Code to execute when the application is activated (brought to foreground)
// This code will not execute when the application is first launched
private void Application_Activated(object sender, ActivatedEventArgs e)
{
InitializeMusic();
}

I'm not sure why but the Source attribute is removed after tombstoning, so try resetting the source in the code behind.
if (App.Current.Resources.Contains("ME"))
{
player =(MediaElement) App.Current.Resources["ME"] as MediaElement;
player.Source = new Uri("/Sounds/mywave.wav", UriKind.Relative);
}

Related

How can I modify a WebView in Xamarin.Forms to open links in a browser on the device?

By default links (<href..>) Xamarin.Forms WebViews open inside the WebView. Especially in iOS where there's no native backbutton that behavior is unconveniend when opening an Url from the internet.
How do I get Xamarin.Forms to let a browser on the device open the links instead, so that it works in at least Android, iOS and UWP?
There is no built-in property or anything that lets you do this.
However, the WebView does have a Navigating event handler. You should be able to hook into that, redirect the user to whatever you want and then cancel the original event. Something like this:
public void WebView_Navigating(object sender, WebNavigatingEventArgs args)
{
if (args.Url.StartsWith("file://"))
{
return;
}
Device.OpenUri(new Uri(args.Url));
args.Cancel = true;
}
To hook it up from code:
var webView = new WebView();
webView.Navigating += WebView_Navigating;
from XAML:
<WebView Navigating="WebView_Navigating" />
More info:
https://learn.microsoft.com/en-us/dotnet/api/xamarin.forms.webview.navigating?view=xamarin-forms

Is it possible to preload an assembly in Windows Phone 7?

I have an app in which I have a lot of references and the load time was not acceptable to me. I have removed the splash screen image and created an animated loading screen by having a separate project with no reference to the main application which then navigates to the first page of the rest of the app. It does start up fast now but it's a little lacking still.
I would like to do another animation right before the load screen goes away. The only way I can think of to do this is to actually preload the assemblies needed for the navigation to the next page, do an animation, and then navigate.
I have tried
OnNavigatedFrom but the animation doesn't have time to run since the page will be replaced by the new page very quickly from that point.
OnNavigatingFrom is no help either as it is called as soon as I call NavigationService.Navigate();
Searching the web and Stack Overflow :)
I also considered faking it a bit by having the next page show a duplicate of the load screen and do the last animation there, but it can't match the current state of the load screen animation and is harder to maintain
Thanks for any ideas!
If you want to force the loading of an assembly, just reference a type from this assembly.
For instance, something like Console.WriteLine(typeof(YourAssembly.SomeType)); will force the loading of YourAssembly.
Now for your problem, maybe you can use usercontrols? Put the content of your main page in a user control. Display the loading page, create the usercontrol in the background, let the animation play, then when the animation is done playing replace the page's content with the usercontrol.
It turns out that you can preload by just creating a new instance of the page you are going to navigate to. Unfortunately that has to be done on the UI thread which can cause animation slowdown, at least in my experience.
Here is a sample of how to do an animation, then preload, then do another animation before navigating. :
public partial class LoadScreen : PhoneApplicationPage
{
public LoadScreen()
{
InitializeComponent();
this.Loaded += OnLoaded;
}
private void OnLoaded(object sender, RoutedEventArgs routedEventArgs)
{
var sb = new Storyboard();
// create your animation here
sb.Completed += (sender, args) => PreLoad();
sb.Begin();
}
private void PreLoad()
{
// this is the part that actually takes time and causes things to get loaded
// you may need it in a try/catch block depending on what is in your constructor
var page = new PageToNavigateTo();
// now create an animation at the end of which we navigate away
var sbOut = new Storyboard();
// create your animation here
sbOut.Completed += (sender, args) => NavigateToNextScreen();
sbOut.Begin();
}
private void NavigateToNextScreen()
{
// navigate here
}
protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
{
base.OnNavigatedFrom(e);
// remove the loading screen from the backstack so the user doesn't see it again when hitting the back button
NavigationService.RemoveBackEntry();
}
}

WP7 MessageBox stops vibrate from happening when displayed

I am having some trouble getting my application to cause the phone to vibrate and play a sound at the same time as displaying a messagebox.
I have managed to get the sound to repeat whilst the messagebox is displayed but I cannot get the vibrate to work at the same time as a messagebox.
I currently use the following code to play a vibrating pulse:
public void vibrate()
{
DispatcherTimer vibrateTimer = new DispatcherTimer();
vibrateTimer.Tick += new EventHandler(vibrateTimer_Tick);
vibrateTimer.Interval = new TimeSpan(0, 0, 1);
vibrateTimer.Start();
}
void vibrateTimer_Tick(object sender, EventArgs e)
{
vc.Start(TimeSpan.FromMilliseconds(300));
}
I then call the vibrate() method. If I call a simple vibrate that plays for say 10 seconds without pulsing then this works however the pulse does not.
Is there anyway around this so I can play a pulsing vibrate while the message box has been displayed?
Thanks
You can use XNA's Guide.BeginShowMessageBox as the message box instead. I believe this doesn't vibrate or play a sound, so you should have full control.

WebBrowser control: show to user when it's navigating

I'm developing a Windows Phone application.
I'm using WebBrowser control and I want to show to users when is loading a page. I've used events:
private void Browser_Navigating(object sender, Microsoft.Phone.Controls.NavigatingEventArgs e)
{
LoadingText.Visibility = System.Windows.Visibility.Visible;
}
private void Browser_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
{
LoadingText.Visibility = System.Windows.Visibility.Collapsed;
}
But it doesn't work.
Any advice?
I think your problem is in the navigated event - this
From msdn
Occurs when the WebBrowser control has navigated to a new document and has begun loading it.
This obviously could be long before the document is actually rendered.
I'm not sure there's any event to use to determine when the page is fully loaded and is rendered.
In iron7, I detect when the editor is loaded by using a timer - that timer keeps trying to call javascript methods in the script - I know these are only available after the document javascript ready occurs.
Try using the LoadCompleted event:
private void Browser_LoadCompleted(object sender, NavigationEventArgs e)
{
LoadingText.Visibility = System.Windows.Visibility.Collapsed;
}
This ensures that once everything is rendered the loading bar will disappear.
See the msdn page: http://msdn.microsoft.com/en-us/library/microsoft.phone.controls.webbrowser.loadcompleted(v=VS.92).aspx
(I think Stuart was looking at the Windows Forms implementation of WebBrowser rather than the Phone Control)

PhotoChooserTask + Navigation

I taken two Images & added event (MouseButtonDown) for them.
When first image handles event to open Gallery. Second image handles events for open camera.
When user has choosed his image from the gallery, I want to navigate to next page. Its navigates. But before completing navigation process, it displays MainPage & then moves toward next page. I didnt want to display the MainPage once user chooses the image from the gallery.
Plz help.
Thanks in advance.
public partial class MainPage : PhoneApplicationPage
{
PhotoChooserTask objPhotoChooser;
CameraCaptureTask cameraCaptureTask;
// Constructor
public MainPage()
{
InitializeComponent();
objPhotoChooser = new PhotoChooserTask();
objPhotoChooser.Completed += new EventHandler<PhotoResult>(objPhotoChooser_Completed);
cameraCaptureTask = new CameraCaptureTask();
cameraCaptureTask.Completed += new EventHandler<PhotoResult>(objCameraCapture_Completed);
}
void objPhotoChooser_Completed(object sender, PhotoResult e)
{
if (e != null && e.TaskResult == TaskResult.OK)
{
//Take JPEG stream and decode into a WriteableBitmap object
App.CapturedImage = PictureDecoder.DecodeJpeg(e.ChosenPhoto);
//Delay navigation until the first navigated event
NavigationService.Navigated += new NavigatedEventHandler(navigateCompleted);
}
}
void navigateCompleted(object sender, EventArgs e)
{
//Do the delayed navigation from the main page
this.NavigationService.Navigate(new Uri("/ImageViewer.xaml", UriKind.RelativeOrAbsolute));
NavigationService.Navigated -= new NavigatedEventHandler(navigateCompleted);
}
void objCameraCapture_Completed(object sender, PhotoResult e)
{
if (e.TaskResult == TaskResult.OK)
{
//Take JPEG stream and decode into a WriteableBitmap object
App.CapturedImage = PictureDecoder.DecodeJpeg(e.ChosenPhoto);
//Delay navigation until the first navigated event
NavigationService.Navigated += new NavigatedEventHandler(navigateCompleted);
}
}
protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e)
{
e.Cancel = true;
}
private void image1_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
objPhotoChooser.Show();
}
private void image2_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
cameraCaptureTask.Show();
}
To my knowledge when you use one of the choosers, like the Photo gallery or the camera, when your application is activating it will take it back to the page you left it. I don't think there is a way to get around this itself. What you would have to do is catch the Activating event in your main page code and Navigate to the desired page from there.
Now I am not completely sure how you would pass the image from the MainPage to the target page. It does not look like there is a property in the Navigation service to store this value. But you could either set it in an application wide variable, ModelView or even store it in the Isolated Storage area.
You could work around this by navigating to an intermediate blank page and have that intermediate page launch the tasks. When the tasks are completed you can then navigate as normal to your new page and only this blank page will show in transit.
Chris is correct that some of the tasks will navigate away from your app (effectively tombstoning it) and will the re-activate your application when the user returns from the task. For the camera this is particularly difficult, as to my knowledge there is no simple way to detect when you are returning from the camera. Also the camera doesn't work when attached to the debugger or Zune software (at least this is true on my HTC Surround), which makes troubleshooting quite difficult!
In my WP7 Barcode Scanning application I ended up using flags on the PhoneApplicationService class to help track where the navigation events are coming from. Something like:
PhoneApplicationService.Current.State["ReturnFromSampleChooser"] = true;
You can then check for these flags in the PhoneApplicationPage_Loaded or OnNavigatedTo method of your main page and redirect to the desired page as needed. Just make sure to clear the flag and be careful to not cause any loops in the navigation, as that might make your app fail certification (back button must ALWAYS work correctly).
For an example of how to use the camera and set/clear flags using PhoneApplicationService check out the source code for the Silverlight ZXing Barcode Library. You can download the full source here or browse the files online.

Resources