There are a number of reasons why you might want to know the identity of someone using your application. Most revolve around the need to store and track personalised information and to be able to uniquely identify any individual user. In your Windows Phone 7 application there are actually three different identities that you may be interested in:
User Id
In order to get the most out of their Windows Phone 7 device (including being able to access marketplace in order to download and install applications and games) a user will need to sign in with a Windows Live Id (or an XBox Live gamer tag). From your application you are able to retrieve a unique identifier that can be used to identify this user. If the same user uses the same Windows Live Id to sign into two different Windows Phone 7 devices and runs your application, the application will see the same identifier. If the same user uses two different Windows Live Ids, then your application will see two different identifiers.
Note that I use the word “identifier”, this is intentional as what you get back doesn’t include any profile information (not even their actual live id) about the user. The following code extracts the 32 character anonymous identifier (ANID) from the UserExtendedProperties class.
private const int IdentifierLength = 32;
private const int IdentifierOffset = 2;public static string UserId()
{
object anid;
if (UserExtendedProperties.TryGetValue("ANID", out anid))
{
if (anid != null && anid.ToString().Length >= (IdentifierLength + IdentifierOffset))
{
return anid.ToString().Substring(IdentifierOffset, IdentifierLength);
}
}return null;
}
Note: To access properties in the UserExtendedProperties class you need to demand the ID_CAP_IDENTITY_USER capability in the WMAppManifest file for your application.
Device Id
Alternatively, you may want to identify each device that your application is being run on (this will help resolve the situation where a single user signs into two devices with the same Windows Live Id). This is done using the DeviceUniqueId property from the DeviceExtendedProperties class.
public static byte[] DeviceId()
{
object uniqueId;
if (DeviceExtendedProperties.TryGetValue("DeviceUniqueId", out uniqueId)){
return (byte[])uniqueId;
}
return null;
}
Note: To access the DeviceUniqueId property you need to demand the ID_CAP_IDENTITY_DEVICE capability in the WMAppManifest file for your application.
Application Id
There are certain cases where you will want to be able to uniquely identify the application (for example, if you write a user control, or a reusable library you might want to be able to identify applications where they are being used). The easiest way to uniquely identify the application is via the ProductID attribute in the WMAppManifest.xml file. eg
<?xml version="1.0" encoding="utf-8"?>
<Deployment >http://schemas.microsoft.com/windowsphone/2009/deployment" AppPlatformVersion="7.0">
<App >
Having to manually extract the ProductID this way is somewhat tedious and from a user control/library developer perspective not very reliable (a developer could pass in the same ProductID for all their applications and thus only pay once). An alternative is to access the WMAppManifest.xml file that gets deployed with the application. When you compile your application it generates a .xap file. This is little more than a compressed file (try changing the extension to .zip and extract the contents) which is expanded into a folder on a Windows Phone 7 device when it is installed. To read the contents of the WMAppManifest.xml file all you need to do is open it the same way as you would any other content that has been packaged with your application.
public static Guid ApplicationId() {
using(var strm = TitleContainer.OpenStream("WMAppManifest.xml"))
{
var xml = XElement.Load(strm);
var prodId = (from app in xml.Descendants("App")
select app.Attribute("ProductID").Value).FirstOrDefault();
if (string.IsNullOrEmpty(prodId)) return Guid.Empty;
return new Guid(prodId);
}
}
That was relatively straight forward…. oh, don’t forget to add a reference to the Microsoft.XNA.Framework assembly which includes the TitleContainer class.
The following screenshot shows the results for each of these identifiers. Note that because this is from the emulator where there is no signed in user, the User Id is null/empty.