Custom Audio notifications with ToastNotificationManager

I struggled to find documentation for this, so I’ve blogged it here for future reference

    ToastTemplateType toastTemplate = ToastTemplateType.ToastText02;
    XmlDocument toastXml = ToastNotificationManager.GetTemplateContent(toastTemplate);

    XmlNodeList toastTextElements = toastXml.GetElementsByTagName("text");
    toastTextElements[0].AppendChild(toastXml.CreateTextNode(title));
    toastTextElements[1].AppendChild(toastXml.CreateTextNode(message));

    var audio = toastXml.CreateElement("audio");
    audio.SetAttribute("src", "ms-appx:///MyAudio/CustomNotificationSound.mp3");
    audio.SetAttribute("loop", "false");

    toastXml.DocumentElement.AppendChild(audio);

    toastXml.DocumentElement.SetAttribute("launch", deepLink);
    ToastNotification toast81 = new ToastNotification(toastXml);
    ToastNotificationManager.CreateToastNotifier(MyAppId).Show(toast81);
About these ads
Posted in Uncategorized | Leave a comment

Inspiron 15R SE 7520 fan always on?

Recently I’ve been getting worried about my Dell Inspiron overheating. The fan was noisy and air expelled was very hot. Looking at the processes running there didn’t seem to be any culprits. Looking at the device manager I noticed that after a recent Windows Update the AMD driver was no longer running. I went to the Dell support site and installed the latest Intel HD followed by (the order is important) the latest AMD drivers – note that these drivers are older than the ones Windows will install. Once installed the device manager showed they were both happy and the overheating seems to have been resolved. I’m guessing this is related to the horribly bungled dual video card implementation on the Inspiron. A more wild guess is that the AMD GPU was probably running all the time and the joint CPU/GPU cooler was probably struggling and hence the overheating problems.

Posted in Uncategorized | Leave a comment

1080p 6 inch Silverlight vs. Jupiter

Anyone know how to resolve this? Given the simple XAML;

<Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="1*"/>
            <RowDefinition Height="2*"/>
            <RowDefinition Height="3*"/>
        </Grid.RowDefinitions>

        <Border Background="Red"  Grid.Row="0" >
            <TextBlock Text="Silverlight"  />
        </Border>

        <Rectangle Fill="Blue" Grid.Row="1" />
        <Rectangle Fill="Green" Grid.Row="2" />

    </Grid>

This results in some very different results;

Silverlight Jupiter
image image

The Silverlight version scales nicely with the phone, whereas the Jupiter version renders the text without scaling it. How do you resolve this?

Posted in UniversalApps, Windows Phone | Tagged | 1 Comment

Controlling the StatusBar (SystemTray) in a Universal App

One of the problems of using Universal Apps is that some components only exist in one platform and not in another. One such example is the StatusBar (formally known as SystemTray) for Windows Phone 8.1. For example, to change the colour of the StatusBar you have to use code rather than xaml. This makes life a bit awkward when you want to use a shared page. So to avoid this issue I’ve created a User Control (ChromeController.xaml) that exists in both platforms;

image

The ChromeController is just dropped into the shared page like any other control, except this one doesn’t have any visuals (I could have used a real control, but I’m being lazy).

User Control

<UserControl
    x:Class="UniApp.ChromeController"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    />

Snippet from shared page;

<Grid>
            <local:ChromeController Background="Pink" Opacity="0.6" />

For the Windows 8.1 variant the code does absolutely nothing, although in the long term it could easily control win81 only assets. However, for the Windows Phone 8.1 it reuses the elements Background and Opacity settings and sets the StatusBar to the same values.

    public sealed partial class ChromeController : UserControl
    {
        public ChromeController()
        {
            this.InitializeComponent();

            this.Loaded += ChromeController_Loaded;
     
        }

        void ChromeController_Loaded(object sender, RoutedEventArgs e)
        {            
            var solidColorBrush = this.Background as SolidColorBrush;
            if (solidColorBrush != null)
            {
                var color = solidColorBrush.Color;
                var statusBar = StatusBar.GetForCurrentView();
                statusBar.BackgroundOpacity = this.Opacity;
                statusBar.BackgroundColor = color;
            }
        }
    }

Here’s the result.

image

Posted in UniversalApps | Tagged , , , | 2 Comments

Using Visual State Manager to share a Universal App page

I was having a chat about how Universal Apps work and how you might use the Visual State Manager to support both Win8 and Phone layouts in a single page.  Here goes;

image

  1. Create a new Universal App
  2. Cut MainPage.xaml from Windows 8.1 and paste it into Shared
  3. Delete MainPage.xaml from Phone
  4. Add a few simple Visual States to represent the screen sizes/orientations you want. In this case I have; MinimalOrPhonePortrailLayout, PortraitLayout, DefaultLayout
        <Grid>
            <VisualStateManager.VisualStateGroups>
                <VisualStateGroup>
                    <VisualState x:Name="DefaultLayout">
                    </VisualState>
                    <VisualState x:Name="MinimalOrPhonePortrailLayout">
                        <Storyboard>
                            <ObjectAnimationUsingKeyFrames Duration="0" Storyboard.TargetProperty="Text" Storyboard.TargetName="SimpleMessage">
                                <DiscreteObjectKeyFrame KeyTime="0:0:0" Value="Phone Layout" />
                            </ObjectAnimationUsingKeyFrames>
                        </Storyboard>
                    </VisualState>
                    <VisualState x:Name="PortraitLayout">
                        <Storyboard>
                            <ObjectAnimationUsingKeyFrames Duration="0" Storyboard.TargetProperty="Text" Storyboard.TargetName="SimpleMessage">
                                <DiscreteObjectKeyFrame KeyTime="0:0:0" Value="Big Device Portrait" />
                            </ObjectAnimationUsingKeyFrames>
                        </Storyboard>
                    </VisualState>
                </VisualStateGroup>
            </VisualStateManager.VisualStateGroups>
            <Grid>
                <TextBlock Name="SimpleMessage" Text="Hello Default World" TextTrimming="WordEllipsis" Foreground="Blue" FontSize="60"/>
            </Grid>
        </Grid>
    
  5. Add a SizeChanged event to the page, this will be used to select the state
            public MainPage()
            {
                this.InitializeComponent();
    
                this.NavigationCacheMode = NavigationCacheMode.Required;
                this.SizeChanged += Page_SizeChanged;
            }
    
            void Page_SizeChanged(object sender, SizeChangedEventArgs e)
            {
                if (e.NewSize.Width < 520)
                {
                    VisualStateManager.GoToState(this, "MinimalOrPhonePortrailLayout", true);
                }
                else if (e.NewSize.Width < e.NewSize.Height)
                {
                    VisualStateManager.GoToState(this, "PortraitLayout", true);
                }
                else
                {
                    VisualStateManager.GoToState(this, "DefaultLayout", true);
                }
            }
    
  6. Add changes to the StoryBoards of the Visual States, in this quick example the text in a TextBlock will be changed.

Here’s the results;

image imageimageimage

imageimage

Hopefully you can see that it is possible to share a single page…although I’m not saying you should ;)

Posted in UniversalApps | Tagged , , , | 1 Comment

HttpClient redirect gotcha

Just a quick post as I’ve just fallen foul of this.

Recently I changed by web-client to use the nice await/async HttpClient, e.g.

   
  HttpClient client = new HttpClient();   
  string result = await webClient.GetStringAsync(serviceRequest); 

The problem is that my service decided to be a good web citizen and change their API by sending a redirect. Unfortunatley the above code simple fell over…legs in the air.

The trick is to configure the HttpClient to allow redirects;

   
  HttpClientHandler handler = new HttpClientHandler();   
  handler.AllowAutoRedirect = true;   
  HttpClient webClient = new HttpClient(handler);            
  string result = await webClient.GetStringAsync(serviceRequest); 
Posted in Windows Phone | Tagged , , | Leave a comment

Getting Value out of Agile Retrospectives

Nice read that had the pleasure of reviewing

Link | Posted on by | Tagged | 2 Comments