I need to control the phone's vibration functionality when the user taps certain elements of my app's UI. I can't figure out how to get access the vibrator though. Is it possible? If so, how do I do this?
Yes it is possible - see Vibration Device class. This code should vibrate your phone:
private void Btn_Click(object sender, RoutedEventArgs e)
{
VibrationDevice device = VibrationDevice.GetDefault();
if (device != null) device.Vibrate(TimeSpan.FromSeconds(1));
}
The above code should work for WP8.1 WinRT, for WP8.1 Silverlight take a look here at MSDN and use VibrateController class.
Related
I'm trying to do something that I thought would be pretty simple, but its not proving that way. I want to play a sound clip from a URI that I'm obtaining from an API. The URI provides an absolute URI to the audio clip.
I've tried using the MediaElement component and that works, except it hangs the UI while the clip is downloading/playing. This means a poor user experience and probably wouldn't get past store certification either.
I've also tried the SoundEffect class from the XNA framework, but that complains about an absolute URI – it seems this only works with relative links and thus wont suffice.
I'm wondering what other options I have for playing a sound clip in a windows phone 8 app that wont hang the UI
Any suggestions welcomed.
Thanks
Using media files on a network or the Internet is going to add latency to the app. You can't start playing the media until the phone has loaded the file. Use the MediaElement.MediaOpened to determine when the media is ready, then call .Play();
Of course, you need to let the users know that the media is downloading. My example uses the SystemTray ProgressIndicator to show the user a message.
XAML
<Grid x:Name="ContentPanel"
Grid.Row="1"
Margin="12,0,12,0">
<StackPanel>
<Button x:Name='PlayButton'
Click='PlayButton_Click'
Content='Play Media' />
<MediaElement x:Name='media1'
MediaOpened='Media1_MediaOpened'
AutoPlay='False' />
</StackPanel>
</Grid>
CODE
private void Media1_MediaOpened(object sender, RoutedEventArgs e) {
// MediaOpened event occurs when the media stream has been
// validated and opened, and the file headers have been read.
ShowProgressIndicator(false);
media1.Play();
}
private void PlayButton_Click(object sender, RoutedEventArgs e) {
// the SystemTray has a ProgressIndicator
// that you can use to display progress during async operations.
SystemTray.ProgressIndicator = new ProgressIndicator();
SystemTray.ProgressIndicator.Text = "Acquiring media - OverTheTop.mp3 ";
ShowProgressIndicator(true);
// Get the media
media1.Source =
new Uri(#"http://freesologuitar.com/mps/DonAlder_OverTheTop.mp3",
UriKind.Absolute);
}
private static void ShowProgressIndicator(bool isVisible) {
SystemTray.ProgressIndicator.IsIndeterminate = isVisible;
SystemTray.ProgressIndicator.IsVisible = isVisible;
}
I have a page on which i am showing multiple youtube videos as webviews. When i play any video, then correspoding video starts playing. But When I click on the back button of the App i should be stop then but its running in background(can hear voice of video).
here is the code of back button:
protected void GoBack(object sender, RoutedEventArgs e)
{
((Frame)Window.Current.Content).GoBack();
}
Tell me how i can dispose of this webview or can stop video.
Thanks
First make sure that the page is finalized; most probably by detaching all the event handlers you manually attached before. Then (sooner or later) the page will be finalized which in turns disposes of the webview.
A similar effect would be achieved by forward navigating the webview to an empty html page.
Here is the solution:
Invoke the UnLoaded event of WebView
- webView.Unloaded += webView_UnLoaded;
Then change the source of the webview in webView_UnLoaded event handler:
Here is my code:
private void webView_UnLoaded(object sender, RoutedEventArgs e)
{
WebView webView = (WebView)sender;
webView.Source = new Uri(" ");
}
I am developing an app on win8 and would like to add an 'AddToFavorites' button on the application bar, so that the user can select his favorites/bookmarks and place them to this. I have added this button to the application bar but the button does not perform any action when clicked.
Currently what I have done is
private async void Favorite_Button_Click(object sender, RoutedEventArgs e)
{
if (SampleDataSource.GetGroup("Favorite").Items.Count != 0)
{
if (this.pageTitle.Text != "Favorite")
this.Frame.Navigate(typeof(ItemDetailPage), SampleDataSource.GetGroup("Favorite").Items[0].UniqueId);
}
else
{
await new Windows.UI.Popups.MessageDialog("You haven't marked any favorites.").ShowAsync();
}
}
But I dont see this functionality working. Any of your suggestions would be of great help to me. It is a Windows8 Metro style C#/XAML App.
Thanks in Advance!
I registered to the OnSizeChanged event of my Page, like that:
private void OnSizeChanged(object sender, SizeChangedEventArgs e)
{
ApplicationViewState myViewState = ApplicationView.Value;
if (myViewState == ApplicationViewState.Snapped)
{
Windows.UI.ViewManagement.ApplicationView.TryUnsnap();
}
}
I'm tyring to set the application-view to Filled/Portrait state when the user trying (manually....) to resize it to snapped view.
but the TryUnsnap method fails and it stays in snapped state...
Help!
Thanks.
To understand TryUnsnap() we need to understand the 2 types of Windows 8 events:
Programmatic events
Programmatic events do not require the user to do anything. For example the Loaded event of a Page or the Tick event of a Timer.
User-initiated events
User-initiated events require the user to do something. For example the Click event of a Button or the Tapped event of a Control.
The important part
Depending on the type of event, only certain Windows 8 APIs can be called. Adding a Secondary Tile, for example. And (as you might have guessed) un-Snapping an app.
That means you can call those APIs all you want from programmatic events but they will never deliver the results you desire. Unsnap in the StateChanged event, and it will fail for this reason. Unsnap in the Button.Click event, and it will succeed for this reason.
The rationale behind this behavior is the user experience. If the app can change it's 'orientation' on the user without the user's interaction then the behavior of the app becomes both confusing and unpredictable. Windows 8 is a pro-user operating system. When you discover developer 'constraints', 99% of the time it is this philosophy behind it.
Let me demonstrate:
If you attached to the StateChanged event, your code would look like this:
this.ApplicationViewStates.CurrentStateChanged += (s, args) =>
{
System.Diagnostics.Debug.WriteLine("After StateChanged: {0}", this.ApplicationViewStates.CurrentState.Name);
if (this.ApplicationViewStates.CurrentState == this.Snapped)
{
System.Diagnostics.Debug.WriteLine("Before Unsnap: {0}", this.ApplicationViewStates.CurrentState.Name);
Unsnap();
}
};
However, the resulting output (in the debugger) would look like this:
After StateChanged: FullScreenLandscape
After StateChanged: Snapped
Before Unsnap: Snapped
After TryUnsnap: Snapped
This is frustrating for a developer who does not understand the difference between programmatic and user-initiated events in Windows 8. The API appears to "not work" when, in fact, it works perfectly. Just not like they want it to.
If you attached to the Click event, your code would look like this:
MyButton.Click += (s, args) =>
{
System.Diagnostics.Debug.WriteLine("After Button.Click: {0}", this.ApplicationViewStates.CurrentState.Name);
if (this.ApplicationViewStates.CurrentState == this.Snapped)
{
System.Diagnostics.Debug.WriteLine("Before Unsnap: {0}", this.ApplicationViewStates.CurrentState.Name);
Unsnap();
}
};
Then, the resulting output would look like this:
After Button.Click: Snapped
Before Unsnap: Snapped
After TryUnsnap: Snapped
After StateChanged: FullScreenLandscape
This gets you what you want, but it brings up an important point. See how After TryUnsnap the state REMAINS "Snapped"? The transition of a Visual State from one to another is not a synchronous event. Calling for a change takes an unpredictable amount of time. It's probably done with a dispatch post, but I would have to check to be sure.
Having said all that, the state does change. And, after the change the CurrentStateChanged event is raised and you can handle the new Snapped state. By the way, it does not matter if there is another snapped app, this works either way.
The MSDN docs say it only works when it is in the foreground. This is pretty stupid since user interaction can't occur on a background app, and background apps have their threads suspended anyway. But, to be fair to MSDN, this API does not work when your app is in the background - whatever that's worth.
I hope this helps clear it up.
And now to your question:
You want to go from Snapped to Portrait? Of course in Portrait, Snapped is not possible so this is not a possibility for you to code. You want to go from Snapped to Filled as soon as the app is snapped. The event raised from the Snapped action is a programmatic event. As a result, you have to lure the user into doing something in your UI first. So, no you can't do what you are asking. You can't Unsnap() until the user interacts with your app somehow (like a button click event).
Oh, and here's the Unsnap() method if you wanted to reference all my code. I am not doing anything special, but you might be interested:
void Unsnap()
{
if (Windows.UI.ViewManagement.ApplicationView.TryUnsnap())
// successfully unsnapped
System.Diagnostics.Debug.WriteLine("After TryUnsnap: {0}", this.ApplicationViewStates.CurrentState.Name);
else
// un-successfully unsnapped
System.Diagnostics.Debug.WriteLine("After TryUnsnap: {0}", this.ApplicationViewStates.CurrentState.Name);
}
Have a great day and best of luck!
var CurrentSnappedState = ApplicationView.Value;
if (CurrentSnappedState == ApplicationViewState.Snapped && !ApplicationView.TryUnsnap())
{
return;
}
Should do the trick. Remember that you can still snap the page, but when you try to do anything in the snapped page you will be redirected to the fullview.
First, a screenshot:
The title and image explain it pretty well. I have an ad set on the right side of my app's main group view (very very similar to the default grid template in this example), and when I pull up my About screen, the ad bleeds through.
The About screen is a user control set on a SettingsFlyout that I borrowed from some code samples handed out at a dev-camp (below).
class SettingsFlyout
{
private const int _width = 346;
private Popup _popup;
public void ShowFlyout(UserControl control)
{
_popup = new Popup();
_popup.Closed += OnPopupClosed;
Window.Current.Activated += OnWindowActivated;
_popup.IsLightDismissEnabled = true;
_popup.Width = _width;
_popup.Height = Window.Current.Bounds.Height;
control.Width = _width;
control.Height = Window.Current.Bounds.Height;
_popup.Child = control;
_popup.SetValue(Canvas.LeftProperty, Window.Current.Bounds.Width - _width);
_popup.SetValue(Canvas.TopProperty, 0);
_popup.IsOpen = true;
}
private void OnWindowActivated(object sender, Windows.UI.Core.WindowActivatedEventArgs e)
{
if (e.WindowActivationState == Windows.UI.Core.CoreWindowActivationState.Deactivated)
{
_popup.IsOpen = false;
}
}
void OnPopupClosed(object sender, object e)
{
Window.Current.Activated -= OnWindowActivated;
}
}
And, because I know it will be asked for, here is the line of XAML defining the ad on my page:
<ads:AdControl Visibility="{Binding IsTrial, Source={StaticResource License}, Converter={StaticResource BooleanToVisibilityConverter}}" Grid.Row="0" Grid.RowSpan="2" x:Name="LandscapeAdControl" ApplicationId="test_client" AdUnitId="Image_160x600" Width="160" Height="600" VerticalAlignment="Center" HorizontalAlignment="Right"/>
So, why is this happening, and how do I prevent it?
Suspicions
I am still on Consumer Preview b/c I have a show-and-tell Monday and didn't have time to work on migrating the OS on this box without risking being non-functional when I am showing this. As such, upgrading might fix it if it's a bug.
1.a. Update I have upgraded to Release Preview and have the same issue.
Is there some fancy ad-hiding-but-still-getting-impressions prevention technique at play here? Perhaps it thinks I am trying to cover the ad with a ui element and still get credit for it's impression without the user seeing it. If so, how do I manage this entirely legit use case?
Spoiler Alert: ZIndex isn't set anywhere.
It presents the same problem with overlaying the AppBar (top or bottom). I used the Opened and Closed events on the AppBar instance to hide/show the ad. This means the AdControl is bound to a local page property instead of binding directly to a ViewModel. Like you said, it's unfortunate but it works.
private void bottomAppBar_Opened(object sender, object e)
{
if (App.ViewModel.IsTrialVisibility == Visibility.Visible)
this.DefaultViewModel["AdVisibility"] = Visibility.Collapsed;
// else do nothing as we don't want to show it since it's not a trial
}
private void bottomAppBar_Closed(object sender, object e)
{
if(App.ViewModel.IsTrialVisibility == Visibility.Visible)
this.DefaultViewModel["AdVisibility"] = Visibility.Visible;
// else do nothing as it's not shown in the first place (not a trial)
}
There is a property on AdControl named: UseStaticAnchor
Setting this property to true will fix both performance problems with scrolling, as well as the AdControl drawing on top of everything else.
Original answer - this method is now outdated:
The AdControl has two methods on it: Suspend() and Resume().
Whenever you open a popup window or AppBar, you will want to call Suspend(), and Resume() when it is closed again.
I believe under the covers, the AdControl uses a WebView to display the ads. For whatever reason, a WebView will always display on top of everything else in your application. The fix for this is to temporarily disable the WebView, and instead display a WebViewBrush.
(This technique is described here: http://msdn.microsoft.com/library/windows/apps/windows.ui.xaml.controls.webviewbrush) So when you call Suspend() and Resume(), the AdControl is doing this under the covers.
What I've ended up doing is creating a UserControl (named SuspendingAdControl) that simply contains an AdControl and can be used anywhere in the app. Then whenever a window is opened or closed, I use Caliburn Micro's EventAggregator to publish an event. The SuspendingAdControl will subscribe and handle these events, and then appropriately call AdControl.Suspend() or Resume().
I ended up crafting some code to listen to an event on the flyout when it closed so I could high/show the ads manually. It's unfortunate that I had to do a workaround, but it works.
None of this is now necessary, as the flyout in 8.1 now is at the top of the Z-order.
I am still on Consumer Preview b/c I have a show-and-tell Monday and
didn't have time to work on migrating the OS on this box without
risking being non-functional when I am showing this. As such,
upgrading might fix it if it's a bug.
I haven't used any advertisements in my own metro applications yet, so I haven't seen any problems like this occurring. I'm using the Release Preview, and was using Consumer Preview prior to May 2nd.
There were some significant changes between the Consumer Preview and Release Preview. As such, upgrading might fix this, or it may break something else.
You're going to have to upgrade eventually. I'd suggest trying that first before you attempt to solve the problem.