blog.reis.se

It's all about looks

The dust from what was presented at Mix11 has long settled and the mango released had been packaged. The tools are with us and we are just waiting for the update to officially reach the phones. So I will do a quick view on background execution in the light of a post I did a few months ago: WP7: Background execution – really?

As it turns out I wasn’t that far from what was presented. Lets go through each point.

The audio service first

What I said around audio service was to make use of:

…the Zune media player. Why would I want to create a new player over and over again? Wouldn’t it be better to integrate with the current? If the API was richer…

It’s just what they provided for us. They call it the Zune service and it’s very easy to use as well. You need of course create a background player agent that is entitled to continue feeding the audio service with tracks to play. The metadata is fully controllable as well using the AudioTrack class that holds lots of information like:

  • Title
  • Artist
  • Album       
  • Tag
  • Duration
  • AlbumArt
  • Source
  • PlayerControls

And as an added bonus it can even be controlled from the web. It will be possible to build an audio player in HTML5 that continues to play the music in the background. Nicely done!

GPS application

My suggestion was to just start the GPS service and start tracking the point in a cache so that not only the current application would access the GPS but also let other application using it at the same time. Also there should be a possibility to trigger a background task on events like each kilometer or every 5 minutes. As we know now, these ideas wasn’t realized in the current version so for RunKeeper and applications like it. It’s still run under screen lock that is the solution.

There are some traces of tracking if you look a bit deeper and do a few undocumented calls. But it’s nothing that is official and an application using it probably wont make it through to marketplace. However, it might very well hint on upcoming functionality and official APIs.

Task scheduling

I also suggested something along these lines of operation:

Why not support some kind of task scheduling instead of true background operation.

Well I missed the naming of this functionality, I should call the code snippets brought back to life agents and I would be spot on. The only exception is the rate of how the agents are run.

Conclusion

In all I think they mostly managed to live up to the users and developers needs here. And now with the mango release fully on its way to the windows phone out there and upcoming models it will certainly be a a lot of fun. 


no_batteryThe last couple of days the battery life on my Windows Phone Mango has been catastrophic. I wasn’t able to last more than 3-4 hours, tops. Then the battery saver icon appeared (battery with a little heart over it) and gave me a couple extra hours, it really is a saver. The only thing that I could think of, that I had changed, was that shuffling the images used as background in pictures hub. So I began to restart, charge, changed settings, disconnected Wi-Fi. I tried all kind of tricks that affects battery life. No luck.

Then I thought that maybe I should stop syncing mail so often and se what effect that would have. When I tried to change my settings I saw how it was syncing mail, lots of mail in my account. It never seem to stop and suddenly it hit me:

I might have set it to sync my All mails folder in my Google mail, and that isn’t a good thing. If it tries to sync all then there is 56 472 conversations dragging around in my Google account (I haven't thrown away any mail, except for spam mail and mailing list, the last 8 years). And even if I narrow this down to the last 7 days it’s a lot of mail to sync in the background. No wonder it was draining the battery. An I was right.

Actually here are a few areas that can improve in the user interface. Doing all this syncing was not good for the performance of the mail application either. I even had trouble to stop the sync of the All mails folder. And while the account was syncing I wasn’t able to remove it or change any settings on it.

In the end I figured that the easiest way to get rid of it all was to just go into flight mode, remove the account and then add it again (after going out of flight mode). This time I made sure it’s just the inbox that is synced. And now all is back to normal again or even better.

So be careful with what you sync or it may really kill the battery on your device.


We (Andreas Hammar and I) are just returning from Tech-Days 2011, we delivered a session on developing applications for Windows Phone 7 in Blend and code. While we were preparing for this session something stuck in our minds - when it comes to mobile applications the top priority is in design and performance.

Design and performance over architecture and frameworks

We have to focus our attention on the user experience, how the application is perceived and not what technology is used or how the application is built. The important thing is that the application is well designed and that it responds to the user. SO to be a WP7 developer there are two things you really have to study, and study hard:

Design
Performance

We're not suggesting that you throw out all the knowledge around architecture and framework. But, if it impacts design and performance you should think twice about why. Also, as Johan Lindfors said in his session – “stop building frameworks! Start building applications”

Slides and samples

Anyway, to sum this up we share the slides on slideshare as well as provide the code and slides as files below.

 

 

Windows Phone 7 in blend and code – code
Windows Phone 7 in blend and code - slides

Resources

Following is a collection of useful links to get started with real development - just promise you don’t build another framework.

Be creative! // Andreas Hammar & Håkan Reis 


Touch is great thing, suddenly you can touch, tap, double tap, flick, pinch and stretch to manipulate virtual object. It really revamped the whole mobile business mainly with the release of the iPhone and the capacitive touch screens, used in most smartphones today. But also in the stuff using infrared matrix screens like the Neonode back in 2004 that had quite good gesture control but never took off.

But let the touch stay there in a virtual interface on the screen. We all know and love what we got there. But if you have a real physical nice button DON'T MAKE IT A TOUCH BUTTON. Physical buttons should stay physical, a touch button is actually just an approximation to the real thing. That was cool in the 80-ties. If you really, really, can't help yourself, at least keep them safe from accidental touch. I’ll give you some example from bad to worse …

WP_000010
The new XBOX 360

This device uses touch to open the tray door and for the on/off switch. Its not a big problem here, the XBOX isn’t moved around much and mostly you don’t touch it by accident. But sometimes, you need to move it. I have it hidden away and I was opening the doors and accidently opened the tray. The sound it made when it hit the wall wasn’t too pleasing but it survived.

WP_000127
My stove

This one is even more annoying. The buttons are placed close to where you normally would have physical buttons and it works well when you and navigate them. But there are a few occasions… If you accidentally cover them they start to do all sorts of crazy stuff until the stove, as a security feature, shut down totally. Also, when you have a big handle cover one panel it reacts,  suddenly you wonder what happen until you realize that you have turned off the heat.

photo (1)
My Samsung Omnia 7

This is by far one of the worst examples of touch buttons. It doesn’t provide any functionality other than looks (and I think you could have gotten the same look with real buttons, with the right materials). It is constantly in the way and trying to play a game is almost impossible as you have your whole thumb over the buttons. I nearly thrown this out the window…

Are there any good versions?

Well I think my old Bang&Olufsen sound system from 1991 is ok, touch button is not a killer feature but adds coolness to this piece of machinery, not that I know what I’m going to use my CD-player or cassette deck for anymore Smile

WP_000008  WP_000012
B&O 4500 with the military grade remote - could easily take out any enemy

It’s also good in that it’s easy to keep clean, it does not produce any false taps or clicks (being placed on a wall and all). It’s only a design thing using touch here but it doesn’t make it worse, besides, it’s the massive one pound remote that is used to control this…

The stove, again, is actually also a good contender for touch buttons:

WP_000014
Easy to clean

There is one really good reasons for using touch here and it compensates for the problems. It’s so easy to keep clean.

So, a final plea!

I first thought of this when I moved in and started the fight with my stove. Then there was mockups leaks of the Windows Phone 7 HTC models. Then when I got my Samsung Omnia 7 in October. I think this is THE most annoying “feature” of the Omnia. But now there as a bigger threat - the mockups that Nokia made for the new Windows Phone 7 models. Look here:

ConceptNokiaWindowsPhones1

This is really scary, touch buttons, and even worse than the Samsung Omnia, the home button is also touch here. This is going to drive at least me crazy. So please forget about touch here!


officeAs you might have seen in the Windows Phone 7 Office application there are small round buttons in the panorama. As you should never use the application bar in the panorama it’s a good way to get some navigation points into the panorama. There are a few versions of this button out, ranging from styling a button and up to complete controls. However the ones I have found have things I don’t like, mostly they work with black and white images or with paths for the icon.

So I started out with a few basic specifications, I wanted:

  • A simple control to use, no special content
  • Only mage for the button (white with alpha channel)
  • To be able to easily add content next to the button
  • Ability to re-skin the button

The goal was to be able to define a button with just a simple:

<jc:RoundButton Image="/icons/refresh.png" Content="refresh" />

For those that don’t want to find out about my journey towards the RoundButton control there is a zip with the code and a sample project at the very bottom of the post…

When I first started out with the basic design the approach was the same as for others out there, two images that was swapped on light theme and shifted on pressed state. But I didn’t like it, I wanted the control to handle the image inversion stuff so my next thought was to create a new image with Writable bitmap and do some pixel magic, but before I got that far I stumbled on a blog post on displaying an image in the accent color. This was brilliant, using the image as a opacity mask, I could have whatever color I liked. So the core of the control got to be something like this:

<Rectangle x:Name="ImageForeground" Height="48" Width="48"
  Fill="with_whatever_color_or_template_color">
  <Rectangle.OpacityMask>
    <ImageBrush ImageSource="image.png" Stretch="Fill" />
  </Rectangle.OpacityMask>
</Rectangle>

The code

On to the control design, first of was to create the code behind for the button, creating the attached properties. This code ended up looking like this:

public class RoundButton : Button
{
    private object _layoutRoot; 
    public static readonly DependencyProperty ImageProperty  = DependencyProperty.Register("Image", typeof(ImageSource), typeof(RoundButton), null); 

    public RoundButton() : base()
    {
        DefaultStyleKey = typeof(RoundButton);
    }
    

    [Description("The image displayed by the button in dark theme (and in normal mode)"), Category("Common Properties")]
    public ImageSource Image
    {
        get { return (ImageSource)GetValue(ImageProperty); }
        set { SetValue(ImageProperty, value); }
     }

    public override void OnApplyTemplate()
    {
        _layoutRoot = GetTemplateChild( "LayoutRoot" ) as Border;
        Debug.Assert( _layoutRoot != null, "LayoutRoot is null" );
        base.OnApplyTemplate();
    }
}

Hurdles and solutions

So the template stuff should be easy now right? Just add the Image to ImageSource for the Brush like this:

<ImageBrush ImageSource="{TemplateBinding Image}" Stretch="Fill" />


Wrong! Turns out you can’t bind to an ImageSource in an ImageBrush, because ImageBrush don’t inherit from FrameworkElement, as BMiloshevska pointed out. Argh, so close. Back to the drawing board until Derek Lakin pointed me at an article about using a converter as a workaround. Here is the converter stuff:

public class ImageBrushConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        BitmapImage image = (BitmapImage)value;
        ImageBrush imageBrush = new ImageBrush();
        if (image != null)
        {
            imageBrush.ImageSource = image;
        }
        return imageBrush;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}


Getting closer, but still there are a few hurdles left as you will see. Now it seems you can bind the ImageBrush to the DependecyProperty with a Converter, like this:

<ImageBrush ImageSource="{TemplateBinding Image, Converter={StaticResource brushConverter}}" Stretch="Fill" />


Wrong again! You can’t use a converter on a TemplateBinding, sigh. Then a new angle: The DataContext. You can TemplateBind the image to the DataContext and then use a normal binding (with converter) for the brush. Success! The binding ended up looking like this:

<Rectangle x:Name="ImageForeground" Height="48" Width="48"
    Fill="{TemplateBinding Foreground}"
    DataContext="{TemplateBinding Image}"
    OpacityMask="{Binding Converter={StaticResource brushConverter}}" />

The template

So now it was the last part left, creating the template style with states for normal, pressed and disabled. The last one is a bonus, with the image approach you would now need three images, white, black and grey, no you can use whatever you like. The template was placed in Themes/generic.xaml and looks in part like this (the full xaml is included in the zip):

<Style TargetType="local:RoundButton">

  <!-- Basic template setters -->

  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="local:RoundButton">
        <Border x:Name="LayoutRoot" Background="Transparent" Padding="12" >
          <VisualStateManager.VisualStateGroups>

          <!-- The states Normal/Pressed/DIsabled/... -->

          </VisualStateManager.VisualStateGroups>

          <!-- The actual button template where the image and content goes -->
          <Grid>
            <StackPanel Orientation="Horizontal">
              <Border Height="48" Width="48" x:Name="ButtonBackground" BorderThickness="3" CornerRadius="24" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" >
                <Border.Resources>
                  <local:ImageBrushConverter x:Key="brushConverter"/>
                </Border.Resources>
                <Rectangle x:Name="ImageForeground" Height="48" Width="48" HorizontalAlignment="Center" VerticalAlignment="Center" Fill="{TemplateBinding Foreground}"
                    DataContext="{TemplateBinding Image}"
                    OpacityMask="{Binding Converter={StaticResource brushConverter}}" />
              </Border>
              <ContentControl VerticalAlignment="Center" Margin="0" HorizontalAlignment="Left" Padding="8,0,0,0" Content="{TemplateBinding Content}" />
            </StackPanel>
          </Grid>
        </Border>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>

There, finally I reached my goal!

Improvements

So am I done now? Yes and no. The functionality is in place and the first four goals reached but there is more stuff I like to do:

  • I want to add some optional animation, for example the push behavior from the AppBar and the tilt effect (actually you can use the tilt effect that Peter Torr blogged about, as the control is based on a button)
  • I think there is a workaround to the Converter, I would like to eliminate that part.
  • Also create a round toggle button with two images (for example play/pause media button)

If anyone happen to have a solution or idea around those issues I would be happy to know.


The zip includes the control and a test project to try it out.


One of the major complaints on the Windows Phone 7 platform is that you can’t run third party applications in the background. I had the same complaint on iPhone for a long time but over the time I have started to think about the problem and I’m not sure background operation for third party application is the only way to solve all the problems.

Let’s look at two scenarios that I think are the most common for background operation: Music player services like Spotify or Last.fm and GPS related applications like the RunKeeper GPS tracker. In these two main scenarios I think a richer and more service oriented API within the phone could take care of the problem instead of background execution.

Lets focus on the audio service first

No doubt that you need it to continue playing music while you work on other stuff. That’s not what I suggest but instead I want you to think of the application that is native in the phone, the Zune media player. Why would I want to create a new player over and over again? Wouldn’t it be better to integrate with the current? If the API was richer, in the Spotify case it would be possible to:

  • Plug in the codec + DRM that’s used in Spotify
  • Create and use playlists from either streamed material or locally stored material – or both
  • Update the background image and access to all the data that is visible in the player
  • Add the playlists as your own into the Zune player and for example mark them with a Spotify icon fro branding

The benefit with this would be many: Apart from not taking up precious development resources for cloning the Zune player over and over, you could let Microsoft take care of creating the most effective background enabled audio/video player.

To the user there is also the benefit of using the familiar way of navigating the audio as always instead of a new one for each application.

Now over to the GPS application

Why do you need to run this in the background? Well there are lots of reasons, but mostly it’s to be able to track and later plot your location from the track you are currently running. This functionality could also be handled with a service similar to the audio service. Why not trigger the GPS service to start tracking and storing the points. This would actually give even more advantages. This way two GPS enable applications could be using the same GPS track store and bring up the points. Again this would let the developer focusing on delivering an awesome application and not how to handle the GPS API effective enough not to drain the battery.

Moving on to task scheduling

There are of course situations where this approach won’t solve your issue but it’s good start to think in other directions when it comes background execution. Why not support some kind of task scheduling instead of true background operation. Here’s an example of what I mean:

In the GPS tracker situation there is an other issue that should be solved. The RunKeeper application vocally reports information on speed, average speed, distance, etc. This would normally be handled with an application running in the background. But it would also be possible to let simple tasks or code snippets be triggered with a set of rules based on the GPS tracker, like time, speed or distance.

I wouldn’t call it multitasking as the application isn’t really running in the background. It is just providing the code that should be brought back to life on certain points and then go to rest again, it can even be fully exited instead of suspended. To the user it would be of no difference if the application is running, suspended or exited as long as it behaves as if it was running in the background.

Conclusion

I think that in many situations we tend to take the obvious solution. While an alternative and for the user actually better way can be achieved if you think twice about it.

And there is an embryo to this in the Zune application, you can let your application launch the Zune player with a URL (either a net stream or locally stored) and it works great. But the API needs to be richer as I would want to insert Metadata and create lists for this as well as be able to provide a codec for handling media streams that Zune cannot play out of the box.

The market will continue to demand background enabling, and Microsoft will probably support that sooner rather than later but I really think we would all benefit from this thinking, both as developers and users.


Building an audio application this weekend I ran into a problem; where do you place the media element when you have more than one page, and you want the audio to continue playing when you navigate between pages. I will get to the solution later on in the post but first some background.

During the weekend our .NET team spent two days with Windows Phone 7. A few weeks ago we brainstormed around a few application ideas. The ultimate goal from the weekend was to se how far we could get in about a day of coding. To get us all kick started we were happy to have Dag König with us to talk about windows phone 7 development and support us during the weekend with ideas and hardware.

We split into several groups and my group focused on an audio application with streaming media, based on listings from an XML source. The available streams were presented in a list and selecting one navigated us to another page where the player was located. Of course there was a lot of different problems solved during this session but one of them was as follows:

We wanted the stream to start playing when we navigated to the Player Page and continue to play in the background when we returned to the stream list in the Panorama Page. It shouldn’t stop until we directly stopped it or a new stream was selected.

After some thinking it was obvious that we needed place that’s globally accessible for the media element responsible for the sound. One such place is the application level, and it turned out to be the way to solve this. But you can’t just drop element in the xaml and be done, that would be too simple. However, the solution wasn’t that far away. I placed it in the common resources instead and used a property to expose it globally for the pages. So the first code part is from the app.xaml file:


  ...
  
    
    
      
      
      
      
      
        
      
    
  

And in the code behind you find the properties parts to make it accessible from the pages in the application (through App.GlobalMediaElement). The property is set the first time the media element is loaded (via the Loaded event) and then it’s just returning the original media element on reoccurring calls:

private static MediaElement _globalAudioElement = null;

public static MediaElement GlobalAudioElement 
{
  get { return _globalAudioElement;  }
}
        
private void OnMediaLoaded(object sender, RoutedEventArgs e)
{
  if (_globalAudioElement == null)
    _globalAudioElement = sender as MediaElement;
}

Finally in the end of app.xaml.cs there is the initialization section and here I injected the global media element in the system with the template from the resource:

private void CompleteInitializePhoneApplication(object sender, NavigationEventArgs e)
{
  if (RootVisual != RootFrame)
    RootVisual = RootFrame;
  
  RootFrame.Navigated -= CompleteInitializePhoneApplication;
  
  // Add this to inject the media element Control template          
  RootFrame.Template = App.Current.Resources["AudioContentTemplate"] as ControlTemplate;
}

And now you can access the MediaElement form any page and do your stuff almost as if it was added the the page itself with:

App.GlobalAudioElement.Source = streamUri;
App.GlobalAudioElement.Play();

That’s all there is to it, hope it helps someone out with the same problem we had. There is actually another solution but that one includes a bit of XNA coding, for this scenario it was enough with the above solution but if you need a more detailed and advanced control over the audio in your application I recommend looking into XNA.

// Håkan Reis