0 Comments

No matter what I did, one Windows Phone 7 app always gave the following error when I tried to play some videos with it using the Microsoft Media Platform:

3100 An error has occurred.

What was worse, the same code and the same video worked in an another app.

Turns out, the reason was simple: Capabilities. In particular, the app was missing ID_CAP_MEDIALIBcapability.

0 Comments

Windows Phone 7 has a anonymous user ID property called ANID. Windows Phone 8 replaced that with ANID2. The difference is that ANID2 is dependent on the app's publisher ID. With ANID and ANID2 you can identify your user. This is helpful for example if you want to store some of her app data in a cloud.

The problem

The problem is that if a user upgrades her phone from WP7 to WP8, her ANID changes. Before, her ANID was same in all of her apps. Now, as the publisher ID is part of the ANID2, her ANID2 will be the same in different apps only if the apps are from the same publisher.

The solution

If you use ANID to identify your users, it maybe useful to always convert the ANID to ANID2. This way, even if your user upgrades her phone, you can still identify her. It’s possible to convert from ANID to ANID2. Microsoft has released a C++ sample on how to do the conversion and this post shows the same algorithm in C#, with a big help from SO.

The code

To do the conversion from ANID to ANID2, you have to have your publisher id (GUID). Also, the WP7 ANID must be in “full” format. Some example code on net shows how you take a substring from the ANID and use that as an ID. Don’t do that. You need the whole ANID (in theory, at least).

Here’s the code which does the conversion:

        public static string GetAnid2FromAnid(string anid, Guid publisherId)
        {
            var anidAsBytes = System.Text.Encoding.Unicode.GetBytes(anid);
            var publisherAsBytes = publisherId.ToByteArray();

            var macObject = new HMACSHA256(anidAsBytes.Take(anidAsBytes.Length / 2).ToArray());
            var hashedBytes = macObject.ComputeHash(publisherAsBytes);

            var result = Convert.ToBase64String(hashedBytes);

            return result;
        }

12 Comments

As we all know, Windows Phone 7 doesn’t have support for in-app purchases. The support was added in Windows Phone 8. This isn’t a huge deal in most countries as WP7 phones weren’t that popular. Except here in Finland. The big problem is that if your app targets Finnish users and you want to provide some content as in-app purchases, you really can’t skip the WP7 users or you’re going to miss a big part of your market. How big you may ask? Over half:

image

The Lumia 800 was really popular here. And it still is as it has been sold with big discounts in the past few months:

image

I’ve been battling with the problem recently as I’ve added some in-app products to an app which targets Finnish users only. And I’m quite happy with the outcome. Here’s first some features of the implementation and then some more details on how it is done:

Features

One XAP

The app only has one XAP (which targets Windows Phone 7.1). The same XAP gets deployed to both WP8 and WP7 phones.

In-app purchases are managed through Dev Center

The in-app purchases are managed through the Dev Center, just like when we are targeting Windows Phone 8 only:

image

One codebase

There’s no “if platform wp 8 then else” code. The product purchase is initiated with the following code:

var license = await store.RequestProductPurchaseAsync("live2013", true);

Native on Windows Phone 8

If the app is run on Windows Phone 8, it uses the native in-app purchase features:

image

Custom code on Windows Phone 7

If the app is run on Windows Phone 7, it uses custom code which mimics the in-app purchase experience of WP8:

image

Note: The WP7 version gets the product details (price etc.) from the Dev Center.

PayPal on Windows Phone 7

User is taken to PayPal’s mobile checkout site when she decides to purchase the product (on Windows Phone 7):

image

On Windows Phone 8 the user can select from any of her payment methods. Remember, the app uses the native in-app purchase functionality on WP8 device.

And that’s about it on the feature side.The best part is that I don’t have to worry about if the user has Windows Phone 7 or 8 device as the same code works on both platforms. Biggest limitation is that the WP7 side is currently PayPal only.

Implementation details

Client

The idea behind the implementation was taken from the code sample “WP8 Store Wrapper for IAP”. The original code sample shows how it is possible to wrap the WP8 store so that it can be used when a WP7 app is run on a WP8 device.

I used a similar wrapping mechanism but in addition I implemented a custom store which is used on WP7 devices. Here’s a StoreFactory-class which decides what store to use:

public static class StoreFactory 
{ 
    public static StoreBase Create() 
    { 
        StoreBase store = null;

        if (Environment.OSVersion.Version.Major >= 8) 
        { 
            store = StoreLauncher.GetStoreInterface("WP8StoreWrapper.Store, WP8StoreWrapper, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"); 
        } 
        else 
        { 
            store = StoreLauncher.GetStoreInterface("CustomStore.MyCustomStore, CustomStore, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"); 
        }

        return store; 
    } 
}

Here’s an example which shows how to check if the user owns product “myproduct”:

var ownsProduct = store.LicenseInformation.ProductLicenses.ContainsKey("myproduct");

Without the wrapper, using directly the Windows Phone 8 SDK, the above code would be written like this:

var ownsProduct = CurrentApp.LicenseInformation.ProductLicenses.ContainsKey("myproduct");

The custom store includes the product details page. The page is similar to WP8’s page, showing the product’s price with the buy and cancel buttons.

Service

The custom store isn’t just a client side thing. There’s a service which the client uses to get the product details and to communicate with the PayPal. The whole thing could be implemented without a service but in that case, if the user changes her phone, the purchase would be lost. With the help of the service, user can install her previously purchased products on a new phone.

The service itself is just a ASP.NET MVC site, which returns the product details to client in JSON format, communicates with PayPal using their old WebService interface and stores the receipts for purchases.

Code

Code isn’t yet available as it needs some fine tuning. But if you’re interested, just give me a shout and can provide more details about the implementation.

0 Comments

We have one Windows Phone app which we have designed to have white background even when the phone’s theme is set to black.

image

The app uses Telerik’s RadPhoneApplicationFrame which provides nice transitions (similar to Navigation Transitions in Windows Phone Toolkit) when a user moves from a page to page.

The problem was that during the transition, the app’s background was shown on black (using the phone’s theme). As we had two pages with white backgrounds but a black transition between them, navigating between the pages provided an irritating experience. It was “flashing”. Here’s a screenshot taken from the app during a transition. Notice the black background:

image

Fortunately the fix was easy: We only had to set the background color of the frame to white:

        protected override PhoneApplicationFrame CreatePhoneApplicationFrame()
        {
            return new RadPhoneApplicationFrame() { Transition = new RadContinuumAndSlideTransition(), Background = new SolidColorBrush(Colors.White) };
        }

1 Comments

I had a simple Portable Class Library project which used Microsoft HTTP Client Libraries (System.Net.Http.HttpClient). The problem: The Visual Studio wouldn’t compile it:

The type or namespace name ''Http'' does not exist in the namespace ''System.Net'' (are you missing an assembly reference?)

The PCL project targeted the following frameworks:

  • Windows Phone 8
  • Silverlight 5
  • .NET 4.5
  • Windows Store apps

I was using the stable 2.1.10 release of the HttpClient library. Resharper didn’t find anything wrong with the code but still it wouldn’t compile. So I created an another PCL project, added the same HttpClient NuGet package and the same code. And it compiled without a problem.

So I had two identical projects with identical references and with identical code. But only one of them compiled.

I decided to diff the project files and this helped me to notice that the non-compiling project had an app.config –file:

image

And the configuration contained bindingRedirects:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="System.Threading.Tasks" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-2.5.19.0" newVersion="2.5.19.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Runtime" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-2.5.19.0" newVersion="2.5.19.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>

When I created the non-compiling PCL project, I set some of the target frameworks wrong. Because of this, it seems, the HttpClient Nuget-package added the configuration. And this broke the compilation after I had fixed the target frameworks.

The solution was simple: I just had to remove the runtime-element from the configuration.