WindowsPhone 8.1, NavigationBar and Silverlight apps #wpdev

With Windows Phone 8.1 Microsoft drastically changed on of the basic chassis requirements in Windows Phone since day 0. The hardware buttons at the bottom of the phone. There were many reasons and one of them was the ability to use same chassis for both Android and Windows Phone devices. This many cited was very important smaller OEMs that recently signed up to Windows Phone ecosystem.

WP7 resolutions:

  • 800 x 480

WP8 resolutions (and scaling factors as reported  by Silverlight apps):

  • 800 x 480     (1.0)
  • 1280 x 720   (1.5)
  • 1280 x 768   (1.6)
  • 1920 x 1080 (2.25)

For Silverlight Windows Phone app (most of the apps that is) the resolution defaults to 800 x 480. This fits nicely with Scaling factor 1.6 which was used by many early Nokia devices. The scaling factor 1.5 however gave 853 x 480. This primarily affected HTC 8 S/X devices and Samsung ATIV S devices only. Later when Lumia 1520 came out, it uses 1020 and that used 2.25 and that also had 853 x 480 res.

What this meant was that WP7 and any WP8 apps that fix their resolution would leave 53 px gap. With my 1Shot camera app, I have a complicated control structure and I ended up fixing many heights and widths.. Not only that I also move certain objects on OrientationChanged using specific values of TranslateX and TranslateY. Last week after a user complaint, I added code to detect 720p and 1080p resolutions and to stretch those by additional 53px. However I never tested this on newer 720p devices that no longer have hardware buttons.

What Windows Phone Dev team did was added another system control like ApplicationBar called NavigationBar. Unlike ApplicationBar, NavigationBar isn’t accessible from within application. Playing with emulator set to show NavigationBar did not show any change in size reported by

double width = Application.Current.Host.Content.ActualWidth;
double height = Application.Current.Host.Content.ActualHeight;

After much complaining around twitter I came across windows phone 8.1 hide NavigationBar post on MSDN Forums. One of the suggestions was using PhoneApplicationFrame.FullScreen. Setting it to true or false made no difference.. none at all. After another round of complains, I came across this post Layout and the Windows Phone navigation bar.. it suggest that SizeChanged event should take care of it and ActualWidth and ActualHeight properties will sort it out.

Being not particularly clever, I thought that Page’s SizeChanged would be fired.. sure it was firing but ActualWidth and ActualHeight were 0.0. Width and Height were NaN so that was useless. Thinking that I could do better than that, I tried using SizeChanged exposed by Application.Current.Host.Content.. nope no difference.. it wasn’t a particularly bright idea.. Yesterday I spent time deliberating whether I should use hardcoded lists to indicate NavigationBar availability or not.. I already do so for high resolution sensors.. nah too much hassle

So today I said.. surely there must be something… on SizeChanged event handler of page, I scanned App.RootFrame.. I found something.. a private field called _visibleRegion correctly showed that 53 px at the botton were not available on 720p emulator when NavigationBar was visible. I think I am clever than most…

private Thickness GetMargin()
{
    Thickness t = new Thickness();

    var field = App.RootFrame.GetType().GetField("_visibleRegion", BindingFlags.Instance | BindingFlags.NonPublic);

    if (field != null)
    {
        object visibleRegion = field.GetValue(App.RootFrame);

        if (visibleRegion != null && visibleRegion is Thickness)
        {
            t = (Thickness)visibleRegion;
        }
    }

    return t;
}

This would get me the right margin and I could just just correct a few bits and bingo.. hahah yah right.. FieldAccessExpcetion eat that you clever git.. Apps don’t run under full trust on phone and I couldn’t reflect to this level. Sigh.. This was hard.. why had Windows Phone team gone way out of their way to piss developers off ?? Having almost lost all hope, I thought, let me try subscribe to Page’s LayoutRoot grid’s SizeChanged event… had a look there.. event handler exposed NewValue and they showed the correct values!!! yay

double gridWidth = e.NewSize.Width > e.NewSize.Height ? e.NewSize.Width : e.NewSize.Height;
double gridHeight = e.NewSize.Width > e.NewSize.Height ? e.NewSize.Height : e.NewSize.Width;

double w = Application.Current.Host.Content.ActualWidth;
double h = Application.Current.Host.Content.ActualHeight;
double hostWidth = w > h ? w : h;
double hostHeight = w > h ? h : w;

bool hasSoftButtons = hostWidth > gridWidth;

Just for your sanity.. I always want Landscape mode so width is always greater than height based on supported resolutions.. so there you have it.. subscribe to LayoutRoot’s SizeChanged and get the right size.. OnResize, the dimensions reflect 800 x 480 resolution and not 853 x 480.

Finally!

Advertisement

DLL / Reference hell with #WP8 #SL81 and #WinRT component

Over the last month, I have gone back to “AlarmClock” app (my 3rd Windows Phone app from back in 2011). I have updated it to render time updates on live tile. In fact I am quite proud the mechanism I use. I additionally provided 50 downloadable font packs that users can choose from (purchasable in a set of 10).

Original solution
The update mechanism was initially based on Silverlight Background Task. The tile update mechanism of course updates tile based on local time. However a user reported that when travelling between timezones, the tiles kept showing previous timezone times until the next background task run started pushing new ones based on new local time.

I deliberated on this and came to the conclusion that somewhere something was fishy.. its possible that Tile updates are actually scheduled on UTC as opposed to local time or maybe I just don’t understand it. Either way, I had to fix this issue

Solution 2: Fix for Timezone change
The new windows phone 8.1 introduced a bunch of new WinRT API that included API for Background task including those that run on Timezone change. So I dumped SL based Background Task and went full stream with WinRT component. Added 2 WinRT classs on for Timer and another for Timezone and this worked great.

Another user wanted the clock and tile updates to support multiple Timezones – wanted to pin Hong Kong and Seattle. My app so far only supported local device timezone.

Soluion 3 – Multiple Timezone support

.NET 4.5 comes with TimeZoneInfo class.This provides a nice method GetSystemTimeZones which lists all timezones and make it possible to convert between those. However Windows Phone .NET Runtime does not come with this and there is not suitable WinRT API either. Yay!!
Oren Novotny created a good Win32 wrapper which works on both WP8, WP81, SL81 and WinRT
I fired up Nuget Package Manager and searched for timezone..found Timezone conversion between WinRT and PCL.. Added a reference to the App and reworked it to support user selectable timezone etc. This required me to select target between x86 and ARM – any CPU no longer an option.

Next step?? Add Timezone helper reference to WinRT component. Bang bang bang.. nugget sorted it all out.. that was easy.. modified the background processor to update all tiles with correct timezone times!! nice 🙂 What could possibly go wrong ?

Hit F6, (Old school.. modified VS 2013 to build o F6 like before).. all good. Hit F5… wait for it !!!!

Runtime exception – File not found System.Runtime.InteropService.. quick search showed reference conflict..

Step 1) Set WinRT component to x86 instead of Any CPU.. maybe that will do the trick!!!

Nope far from it… Result System.BadImageFormatException thown when trying to run the app.

Step 2) Download code and make a part of existing WinRT component..

Nope still the same error(s)

While deliberating, realised that I called code from Background Task directly from my app.. 3rd trial

Step 3)

Remove calls to code in Background Task from App
Nuget Reference to App
Code within WinRT component for internal use
App – x86 / ARM target
WinRT component – Any CPU tagt

Bingo.. It all work as advertised!!

Took me day to figure try out various options

Monetization on Windows Phone and 8 Stores #wpdev #win8dev

Let me start by stating a few simple facts:

  1. I received first payout from Windows Phone Store after 6 months
  2. I receive regular payouts from Pubcenter – more so than store payouts
  3. I received first payout for Windows 8 store after about 15 months.

There are multiple factors that most likely contribute to what platform gives better payout. I don’t have the same apps on both platforms. Apps I created overlap but Windows Phone has many more apps than Windows 8.

Unless you have a fantastic reputation, you will need to offer Trial for you apps. The experience and API offered by SDKs are simple – it only takes into account current usage. There is no historic knowledge of what you did before. You can download a trial, use it and reinstall it and get another trial. If you don’t like this, you as a developer will have to implement checks using ANID etc.

If you don’t offer trials, you will have limited downloads.

Since Windows Phone 8 release, we know have IAP. so the Fremium model now has another option. Before you get overly excited here are some more observed behaviours.

  1. Most users will continue using an app
  2. Most people will continue using the app as long as you provide options for it to continue working while in limited functionality mode.

Let me explain: 2 of my apps have a model where I block functionality if its a free app and user navigates away from the app. In one case I stop background music player and in other I disable app specific alarms. Both of these work fine as long as the app is active and what I noticed was that instead of paying $0.99, users will continue using app with ads and restrictions.

if you think user will pay to get rid of apps, think again. sure there is money to be made from ad-revenue. however let me give you more food for thought.

  1. Most ad networks only pay per click –  biggest and baddest out there is Admob – the google monstrosity 🙂 You can display millions of impressions yet fail to generate a penny unless your user clicks on the ad.
  2. There are a few providers which pay per impression however the ePCM is lower and if you get clicks, the ePCM rises.
  3. ePCM is measure in a chunk of 1000. for an app that attracts 0 clicks, your ePCM will be around 8 – 10p.
  4. If an app does not display say 1000 ads in a day, you wont see any revenue. like I said, works in a chunk of 1000, all or nothing.
  5. Windows Phone developers traditionally used Pubcenter as it gives a pay per view model however it only pays for a few markets – North America and Western Europe. If your user base is elsewhere you will see little.
  6. For other markets use other ad providers, user ad rotator and try different providers and see what they generate.
  7. If you want ad revenue, make games or apps for kids.
  8. If you are doing Windows 8 development, don’t bother with pubcenter 🙂 Its a waste of time. In 1+ year I can bet that its not generated £1 in total still date even though it has received thousands of requests – there are no ads to serve.

If you think that your app will be user for substantial periods, ad supported fremium makes sense. Make sure you think about ways in which user can just navigate away yet continue using the functionality. Finally if you want user to pay up, restrict the apps.

Sorry not a very cheerful post for a Monday 🙂 Happy coding

walking directions with using Uri Navigation #wpdev

In past, I usually opened the map control and set the location to that of the cinema. The user can then tap route option to plot the route.

Recently I decided to use HERE maps launchers to do the same.. however Glenn Versweyveld suggested that I should rather use How to request driving or walking directions for Windows Phone 8.

Using that was equally easy.. you craft a Uri and then you launch it. the system takes care of lauching drive / walk apps appropriately.

Being a good developer, I wanted to assign a name to location shown on maps so I used Destination.Name parameter with something like “Cineworld – London Enfield” being my closest cinema.

When using ms-drive, Nokia HERE Drive+ launched correctly and display destination and driving directions.

However using ms-walk, Nokia HERE Maps would start but show users current location.. nothing about destination.. totally ignored. I tweeted my frustration and Randall Arnold mentioned that he had lots of issues with ms-drive and ms-walk and that it would ignore everything after ‘-‘ character.

So I stripped ‘-‘ out of destination but still nothing. so I decided to strip blank space ‘ ‘. Instead of specifying the whole “Cineworld – London Enfield”, I just set Destination.Name to “Cineworld”. Bingo.. HERE Maps launches with correct destination and walking directions.

Job done.

Install Windows on a UEFI device and #wpdev sdk issues

When I got the Haswell ultrabook from Intel, it had a Windows 8 x64 build. I eventually upgraded to Windows 8.1 but I faced issues when trying to hibernate / shutting it down. This seriously affected my hobbyist dev as a I tend to leave stuff open and hibernate the device.

So to solve the problem I tried to reinstall Windows 8.1 using USB key (using Windows 7 USB / DVD tool).. however the boot loader would just ignore it and revert back to boot selection screen. I eventually reinstalled the PC using Windows 8.1 Clean and refresh option and that works as advertised. But I had some issues when installing WP8 sdk.

wp8sdk

I tried in vain to install it but it wouldn’t have anything. Eventually I figured I had to do a clean install of Windows 8.1 so scouring the next, I came across this post… the tool Rufus is almost identical to stock format tool crossed with usb dvd tool 🙂

rufus

That worked, the UEFI bootloader finally allowed me to install using usb key however I still have the same issue with WP SDK. Turns out some certs were out of date. I again checked for root certificate update and downloaded tool from Windows Catalogue but that didn’t do much either..

so finally I reset the system date to the day I got the device.. I remember install WP SDK then and bang it installed just fine.. silly bugger

So how did I get #GDR2 for #Lumia920

I have been debating whether to pay up for Navifirm to be able to find and install GDR2 for Lumia920. I remember Andy Wilson paying up and tweeting that he couldn’t find his devices firmware there. So I decided its not worth going down XDA-developers route, instead I could just wait a bit.

Yesterday evening, Wolfgang Ziegler, tweeted that he installed #GDR2 on his device and I said.. that’s it.. bloody hell.. time to get on with it.

So like my usual cheerful self, I quickly glanced at the post, downloaded Nokia Software for Retail 3.0.8 and back.. I have an update waiting to install.. blimey.. proceed without caution 🙂

Didn’t I say my usual self ?

1.3 gig download, installed in 10 mins, after configuration, of course bloody backup can’t be used as by default APN isn’t set and data connection is off.. hang on.. it was working fine when I reset the Lumia925.. quick check.. damn what.. no Amber / GDR2.. how the hell..

Oh well I suppose it was intermediate update.. plug in again and bang.. NSR says another update waiting to be installed.. for the first time I actually paid attention to the update version.. bloody thing was asking me to update the same version and forcing ROM overwrite each time..

Damn you Hermit Dave.. stupid git.. never read the instructions.. RTFM.

While trying to find Nokia Software for Retail, I remember being tempted into reading How to download Nokia Firmware with Nokia Data Package Manager.
So next step.. download and install Nokia Data Package Manager.. input correct details and search.. oops latest version is same as the one shown in NSR.

Another idea.. last year when I was hacking about trying to install 7.8 on Lumia800, I downloaded another firmware, remained a few files to match the product code and then used Nokia Care Suite. Quick check.. already had latest Nokia Care Suite – installed while I was deliberating 🙂
back to Wolfgang Ziegler blog, downloaded the ROM for his device 🙂 A quick rename and tried flashing with NSR and NCS.. ooops some files are missing.. nope rename wouldn’t do…

Check on XDA-Developers said you can install other ROMs.. as long as you just pick the version, start programming, select ROM and then plug the device when prompted.. did that, it said.. product codes don’t match.. Proceed ? Hell yes.. 10 mins flashing and after a few nervous minutes.. device up and running and bang.. backup worked as APN was set correctly like on Lumia925.. wohooo looks like I have GDR2.. quick check proved that to be the case 🙂

Job done..

Persistent Thread like behavior with #win8dev

As you might have gathered, I
* like writing bad code
* doing things that people frown upon (like writing bad code)

Ever since I started Windows 8 Development, I miss Threads in all their glory. Sure Async Task is mostly fine but its not the same. Earlier today, Arafat asked a question about truly async logging mechanism. I suggested hacking Async Task into a thread like behaviour 🙂 – actually it just gets you a threadpool thread 🙂

Task.Run provides a mechanism to queue given code on a ThreadPool for parallel execution. What happens when you refuse to return the method ? well you get the ThreadPool thread as your personal bitch 🙂

CancellationTokenSource CancellationSource = null;
CancellationToken TaskCancellationToken;

private async void AlwaysOnLoggingAsyncTask()
{
     while (!this.TaskCancellationToken.IsCancellationRequested)
     {
          // do something.. actually do anything
          // in the sample I was mucking around with StorageFile
          // hence the async void 

          await Task.Delay(1000); // don't kill the PC by running a tight loop.
     }
}

private async void btnStart_Click(object sender, RoutedEventArgs e)
{
     CancellationSource = new CancellationTokenSource();
     this.TaskCancellationToken = CancellationSource.Token;
     Task.Run(() => this.AlwaysOnLoggingAsyncTask(), TaskCancellationToken);
}

private void btnStop_Click(object sender, RoutedEventArgs e)
{
     CancellationSource.Cancel();
}

Here’s a dummy sample logging project that incorporates this bad code 🙂

Update: since I was writing really bad code, I deliberately forgot to add Task.Delay. If you prefer to not write code that makes system a bit less miserable, consider adding a Task.Delay of about 1000 (1 second)

Update 2: Jarno pointed out that I am writing really really bad code – mechanism dating pre-Task era – which is correct. Old habits die hard. Well I’ve update the blog plus source 😛 to use Task Cancellation Token

Super Duper All in one VisibilityConverter for #wpdev

On the 4th of July I blogged about simple visibility converters to toggle visibility. Of course I used two converters then.. one Visibility and another inverse aka Invisibility.

I also said that some clever people might tell me that its possible to do both in a single converter. Whilst that is true, no one did so apparently no one really reads or cares 😐 Coding4Fun toolkit has a converter than exposes Inverted property but my idea was to be able to use the same converter by pass a parameter.

So here’s what I did

 

public class VisibilityConverter : IValueConverter
{
    public enum Mode
    {
        Default,
        Inverted,
    }

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        Visibility returnVisibility = Visibility.Visible;
        Mode mode = Mode.Default;
        try
        {
            if(parameter != null)
                mode = (Mode)Enum.Parse(typeof(Mode), (string)parameter, true);
        }
        catch 
        {
            mode = Mode.Default;
        }

        if (value == null)
        {
            returnVisibility = Visibility.Collapsed;
        }
        else if(value is bool)
        {
            bool bVal = (bool)value;
            if (!bVal)
                returnVisibility = Visibility.Collapsed;
        }
        else if (value is string)
        {
            string itemVal = value as String;

            if (String.IsNullOrWhiteSpace(itemVal))
                returnVisibility = Visibility.Collapsed;
        }
        else if (value is IList)
        {
            IList objectList = value as IList;
            if (objectList == null || objectList.Count == 0)
                returnVisibility = Visibility.Collapsed;    
        }

        if (mode == Mode.Inverted)
            return returnVisibility == Visibility.Visible ? Visibility.Collapsed : Visibility.Visible;
        else
            return returnVisibility;
    }

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

and how do I use it ? well this is how

<TextBlock Text="{Binding Review}" Visibility="{Binding Review, Converter={StaticResource VisibilityConverter}}" TextWrapping="Wrap" Style="{StaticResource PhoneTextNormalStyle}" Grid.Column="0" Grid.Row="1" Grid.ColumnSpan="2"/>
<TextBlock Text="(rating only)" Visibility="{Binding Review, Converter={StaticResource VisibilityConverter}, ConverterParameter=Inverted}" Foreground="{StaticResource PhoneSubtleBrush}" TextWrapping="Wrap" Style="{StaticResource PhoneTextNormalStyle}" Grid.Column="0" Grid.Row="1" Grid.ColumnSpan="2"/>

I could pass Default parameter or just leave it out and it defaults to normal behaviour. If I however pass Inverted parameter to the converter, it inverts the behaviour. Bingo.

Now waiting for the next clever people to tell me that I am using parameter designed for something else 🙂

How to renew your Windows Store subscription using MSDN code

If you have an msdn account, you get codes for registering on both Windows Phone and Windows Store. These allow you to submit apps and generate revenue (potentially) for free since you are already playing for MSDN.

Last year while waiting for my app to be approved by App Excellence Lab, this feature was announced and having gone through 3 different AEL sessions, I found it easy to register account using MSDN provided code 🙂

Its almost a year since that day, I haven’t managed to generate enough revenue to pay for it but I am fortunate enough to have MSDN account and have a code at hand.

The notification email advises heading to https://commerce.microsoft.com and renewing there – alternatively you do nothing and they charge your card.

Visiting the above site, I only saw renewal options paying by card / Direct Debit or paypal.. no option to use MSDN code. I kept looking around and here’s how you do it. Copy code to clipboard and navigate to http://dev.windows.com/

Account

From dashboard, click Subscription and then click Renew button. You will get this page

code

Paste your MSDN supplied 7 character code and hit update total. After a few checks the total should be displayed as 0.00. Click Next and follow through.

Note: If your card has expired or is invalid, you will get Invalid session message and it will prompt you to start again. Click Signin and enter new card details (it needs a valid card even though you are paying 0.00) and complete the process.

Done.. you will get a confirmation email when you have completed the process. Lets hope this year brings more financial rewards to Win8dev

Background Audio #win8dev #winrt

In this post I am going to detail some of the work I have been doing on Background Audio. But before I get onto it, let me say that the last few months have been crazy / busy, not highly motivational for personal dev etc. I have done a few updates over the last few months but no new development until this month.

About 2 weeks back I started work on Porting Slydr code to WPF control and that was a breeze. Infact last night I saw something about a simple app being tested.. makes me think on whether I should beat them to it 🙂 or not.

Now back to Background Audio. With Windows Phone, one had to create a Background Audio Player which the app and system would then communicate with. The app could kick the Background Audio Player off and then exit and the audio would keep on playing. I have talked about this before and will saying it again. WPDev 7x provided many ways of playing audio. With Windows 8 and #WinRT your options are restricted. I have gotten used to giving MediaElement more usage and credit for what it does.

<MediaElement x:Name="mePlayer" />

All you need to do is set the Source property and then call Play(). The audio starts playing. If the app gets suspended, the music stops playing. To enable background audio there are a number of things you need to do.
* Firstly set MediaElement‘s AudioCategory to BackgroundCapableMedia. This still doesn’t activate the Background Audio as its only the first step

* Now open package.appmanifest file. Open the Declarations tab and add Background Tasks. While you are there set the Supported task types property to Audio and Control Channel. You will also need to set the Start page in App settings. Of course now that you have done this, you will have to create a Badge logo before you can save the changes to appmanifest.
appManifest

* Now back to codebehind of your page and add event handlers for MediaControl‘s PlayPressed, PausePressed, StopPressed and PlayPauseTogglePressed events

In my app I also support Previous Track / Next Track so I additionally added support for PreviousTrackPressed and NextTrackPressed events.

MediaControl.PlayPressed += MediaControl_PlayPressed;
MediaControl.PausePressed += MediaControl_StopPressed;
MediaControl.StopPressed += MediaControl_StopPressed;
MediaControl.PlayPauseTogglePressed += MediaControl_PlayPauseTogglePressed;
MediaControl.NextTrackPressed += MediaControl_NextTrackPressed;
MediaControl.PreviousTrackPressed += MediaControl_PreviousTrackPressed;

and

void MediaControl_PreviousTrackPressed(object sender, object e)
{
    this.Previous();
}

void MediaControl_NextTrackPressed(object sender, object e)
{
    this.Next();
}

void MediaControl_PlayPauseTogglePressed(object sender, object e)
{
    if (MediaControl.IsPlaying)
        this.Stop();
    else
        this.Play();
}

void MediaControl_StopPressed(object sender, object e)
{
    this.Stop();
}

void MediaControl_PlayPressed(object sender, object e)
{
    this.Play();
}

Now when you run the app, initiate the audio playback and navigate away from the app.. Bingo. the audio is still playing.