http://msdn.microsoft.com/en-us/library/windowsphone/develop/jj735579%28v=vs.105%29.aspx
According to the document when I use fast resume in windows phone 8 I can resume my App from main tile.
But when my app is tombstoned ,
for example, mainPage can navigate to ->pageA can naviget to->PageB, I deactived the app from PageA, then the
app is tombstoned, when I click the Tile that navigate to PageB, it's strange that the app back to Page A .
How to fix this problem?
It sounds like you are not saving the application state before it is tombstoned. There are 4 events that are fired for preserving application state:
These are related to completely closing and reopening the application (eg: Phone restart)
Application_Launching
Application_Closing
These are related to tombstoning (task switching)
Application_Activated
Application_Deactivated
It sounds like what you need is the second one relating to activating / deactivating. These methods are placed in the Applications *.cs file and allow you to preserve and reinstate the ViewModel when tombstoning.
This is an example:
private readonly string ModelKey = "Key";
private void Application_Deactivated(object sender, DeactivatedEventArgs e)
{
PhoneApplicationService.Current.State[ModelKey] = ViewModel;
}
private void Application_Activated(object sender, ActivatedEventArgs e)
{
if (PhoneApplicationService.Current.State.ContainsKey(ModelKey))
{
ViewModel = PhoneApplicationService.Current.State[ModelKey] as FeedViewModel;
RootFrame.DataContext = ViewModel;
}
}
Related
I am developing a Xamarin Forms application which is basically a WebView where the user have access to some files which is supposed the user have to be able to download.
To achieve this in Android, I have this CustomRenderer for the WebView in the Android project, basically I get the cookies (files are under authentication) to send them to the DownloadManager:
public class CustomWebViewRenderer : WebViewRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.WebView> e)
{
base.OnElementChanged(e);
if (e.NewElement != null)
{
var customWebView = Element as CustomWebView;
Control.Settings.AllowContentAccess = true;
Control.Settings.AllowUniversalAccessFromFileURLs = true;
Control.Settings.DomStorageEnabled = true;
Control.Settings.JavaScriptEnabled = true;
Control.Download += OnWebViewDownload;
}
}
private void OnWebViewDownload(object sender, DownloadEventArgs e)
{
var source = AUri.Parse(e.Url);
var request = new DownloadManager.Request(source);
request.AllowScanningByMediaScanner();
var cookieString = CookieManager.Instance.GetCookie(e.Url);
request.AddRequestHeader("Cookie", cookieString);
request.AddRequestHeader("User-Agent", e.UserAgent);
request.SetNotificationVisibility(DownloadVisibility.VisibleNotifyCompleted);
request.SetDestinationInExternalPublicDir(AEnvironment.DirectoryDownloads, source.LastPathSegment);
var manager = (DownloadManager)MainActivity.Current.GetSystemService("download");
manager.Enqueue(request);
}
}
The download starts in the background and everyone is happy.
My problem started when I noticed that this behavior is not available in iOS, since the file is displayed on the webview not giving me any option to download or showing the "Open in..." dialog. In plus, after trying to implement a CustomRenderer for the iOS platform too, I see no handler, property or method in the UIWebView or the WKWebView which allows me to manage the download or share the file in another app.
I need to be able to download the file in iOS, or at least, show the "Open in" bar. Any suggestions? Thanks in advance.
The download is started by the user clicking on the Download File button. The Xamarin.Android application utilizes a ProgressBar widget to display the download progress.
The button that begins the download has the following asynchronous event handler assigned to it's Click event:
async void StartDownloadHandler(object sender, System.EventArgs e)
{
_progressBar.Progress = 0;
Progress<DownloadBytesProgress> progressReporter = new Progress<DownloadBytesProgress>();
progressReporter.ProgressChanged += (s, args) => _progressBar.Progress = (int)(100 * args.PercentComplete);
Task<int> downloadTask = DownloadHelper.CreateDownloadTask(DownloadHelper.ImageToDownload, progressReporter);
int bytesDownloaded = await downloadTask;
System.Diagnostics.Debug.WriteLine("Downloaded {0} bytes.", bytesDownloaded);
}
In the previous code snippet, the Progress encapsulates a lambda that will update ProgressBar, displaying the percentage of bytes that were downloaded. It is important to realize that Progress will execute in the same SynchronizationContext it which it was instantiated. So, because Progress is created on the UI thread, it will run in the UI thread. It is not necessary to explicitly use RunOnUIThread inside the provided lambda to update the UI.
I dont see DownloadHelper on xamarin.android. I want to create a download method
I am developing a windows 7 phone app where I want a particular page( A privacy policy which the user needs to accept ) to be displayed when the user uses the app for the first time in his phone. Can any one please tell me how to get this done.
Two approaches can be taken for this functionality. The first is to always start at the privacy policy page but override the OnNavigatedTo method to check if the policy has been accepted before. If it has, navigate to your "MainPage". Within the Mainpage, remove all backstack entries.
Privacy Policy Page
protected override void OnNavigatedTo(NavigationEventArgs e)
{
// have the accepted the policy?
var settings = IsolatedStorageSettings.ApplicationSettings;
bool accepted;
if(settings.TryGetValue("PolicyAccepted", out accepted))
{
if (accepted)
{
NavigationService.Navigate(new Uri("MainPage.xaml", UriKind.Relative));
}
}
}
private void OnAcceptButtonClick(object sender, RoutedEventArgs routedEventArgs)
{
var settings = IsolatedStorageSettings.ApplicationSettings;
settings["PolicyAccepted"] = true;
settings.Save();
NavigationService.Navigate(new Uri("MainPage.xaml", UriKind.Relative));
}
Then in your MainPage, remove the backstack
protected override void OnNavigatedTo(NavigationEventArgs e)
{
while (NavigationService.CanGoBack) NavigationService.RemoveBackEntry();
}
The second approach is to is a UriMapper as described in this SO answer.
A possible answer to this question can be found here. As you want your page to open up only once I suggest IsolatedStorageSettings to save a boolean value if the user has accepted the policy or not.
How to I get access NavigationService in a Windows Phone app without going through a PhoneApplicationPage? My goal is to pass it to the application's primary view-model on startup, a technique that worked quite well for me in WPF and Silverlight.
You can get it from the app's PhoneApplicationFrame. It will be accessible from anywhere in the app since every Windows Phone app has a Frame.
((PhoneApplicationFrame)Application.Current.RootVisual).Navigate(...);
Another place to get it is from the RootFrame field in the default implementation of Application:
#region Phone application initialization
// Avoid double-initialization
private bool phoneApplicationInitialized = false;
// Do not add any additional code to this method
private void InitializePhoneApplication()
{
if (phoneApplicationInitialized)
return;
// Create the frame but don't set it as RootVisual yet; this allows the splash
// screen to remain active until the application is ready to render.
RootFrame = new PhoneApplicationFrame();
RootFrame.Navigated += CompleteInitializePhoneApplication;
// Handle navigation failures
RootFrame.NavigationFailed += RootFrame_NavigationFailed;
// Ensure we don't initialize again
phoneApplicationInitialized = true;
}
// Do not add any additional code to this method
private void CompleteInitializePhoneApplication(object sender, NavigationEventArgs e)
{
// Set the root visual to allow the application to render
if (RootVisual != RootFrame)
RootVisual = RootFrame;
// Remove this handler since it is no longer needed
RootFrame.Navigated -= CompleteInitializePhoneApplication;
}
#endregion
I'm creating a little app to help me better understand how to play sounds on WP7 devices but I'm having a problem actually getting the sound to come out of the device.
I have the following code:
<MediaElement x:Name="note1" Source="test.mp3" AutoPlay="False" />
private void btn1_Click(object sender, RoutedEventArgs e)
{
note1.Source = new Uri("test.mp3", UriKind.Relative);
note1.Play();
}
Where test.mp3's Build Action is a Resource.
The thing I don't understand is when I add a breakpoint on the method btn1_Click and I stop at note1.Play() it actually plays test.mp3 but when debug without breakpoints and click on the button I hear nothing.
Is there a way to fix this issue?
Have you tried playing with test.mp3's Build Action set as content.
Also did you close zune software after it recognizes the phone and completes sync, and connect using wp7connect tool. for more info about wp7connect tool try here.
zune locks all media on wp7 device and you cant play any media, but the status of the media will be "ended".
try setting up media's following events MediaFailed MediaOpened,MediaEnded, DownloadProgressChanged, CurrentStateChanged and BufferingProgressChanged
Also, make sure you have add the capability ID_CAP_MEDIALIB to your manifest (WMAppManifest.xml), this seems to be required for MediaElement (otherwise you'll get AG_E_NETWORK_ERROR in your MediaFailed handler).
i dont recommend mediaElement for more than one audio item ..it has weird effects ...use something like:
Stream stream = TitleContainer.OpenStream(#"Audio/buzzer.wav");
SoundEffect effect = SoundEffect.FromStream(stream);
FrameworkDispatcher.Update();
effect.Play();
using the xna framework ....and make sure there WAV files.
Uri kind must be RelativeOrAbsolute.
private void btn1_Click(object sender, RoutedEventArgs e)
{
note1.Source = new Uri("test.mp3", UriKind.RelativeOrAbsolute);
note1.Play();
}
You need to make sure the MediaElement has been opened before you can call .Play() on it - you can do so by adding an event receiver to the MediaOpened event. It would also be good to call .Stop() any time prior to reassigning the Source property - take a look at this thread for more details.
This can't be solved without an Eventhandler. Do as mentioned below.
<MediaElement x:Name="note1" Source="test.mp3" AutoPlay="False" />
private void btn1_Click(object sender, RoutedEventArgs e)
{
note1.Source = new Uri("test.mp3", UriKind.Relative);
note1.MediaOpened += new RoutedEventHandler(note1_MediaOpened);
}
void note1_MediaOpened(object sender, RoutedEventArgs e)
{
note1.Play();
}
this is perfectly works. enjoy...