Developers need to understand
the state of a device in order to provide the best experience for end
users, such as letting the user know when a large download is about to
begin and asking if the user would like to switch to a wireless or
Ethernet connection via USB.
In this section, we cover the
different pieces of device status and information that are available
via the Windows Phone 7 APIs, including User Identifiers, Device
Identifiers, Network Status, and Device capabilities.
Most of the code for device
information is simply a matter of displaying string-based properties so
the only code listed in this section is for network availability info
below. Otherwise, please refer to the DeviceInfo project in the source code for additional detail. The next subsection starts with user and device identification first.
1. Identifying Unique Users
There is a properties
class for user information available in this release of Windows Phone 7,
which is contained in the Microsoft.Phone.Info.dll. It supports exactly
one value, Anonymous Identifier ANID, which can be used to identify the
user. Here is the full namespace, class, and method calls to obtain a
user identifier:
Microsoft.Phone.Info.UserExtendedProperties.GetValue("ANID")
Microsoft.Phone.Info.UserExtendedProperties.TryGetValue("ANID")
How unique is this ID? It
identifies the user with the same value, even if the user owns multiple
phones. This value is persisted across reboots. Even if you
factory-reset the phone, but configure it with the same Live ID, you
will get the same value for the ANID property.
NOTE
The ANID property returns an empty string in the emulator.
Using this property requires the user identity capability and the ID_CAP_IDENTITY_DEVICE entry in the Capabilities section of WMAppManifest.xml
for the application. If an application uses this class, the user will
be alerted that the application requires this capability in the Windows
Phone marketplace. You should only use this capability if your
application absolutely needs it, and if it provides direct benefit to
the user in some fashion. For example, if it makes it possible to store
and retrieve from the cloud settings and data tied to the ID. Developers
should mention the benefit in the application description; otherwise,
users may be less inclined to download your application.
2. Device Information
There is a separate properties class for device information in Microsoft.Phone.Info.dll called DeviceExtendedProperties.
It provides the ability to uniquely identify a device. Unlike the
UserExtendedProperties class, the DeviceExtendedProperties class
supports more than one value. The method call is the same as for the
user property:
Microsoft.Phone.Info.DeviceExtendedProperties.GetValue()
Microsoft.Phone.Info.DeviceExtendedProperties.TryGetValue()
Table 1 lists the possible values that can be passed into the above method calls.
Table 1. Possible DeviceExtendedProperites Values
Value | Description |
---|
DeviceManufacturer | The
name of the manufacturer of the device. A different value may be used
across different devices from the same manufacturer, or it may be empty. |
DeviceName | The name of the device. There are no rules enforced on naming and it may be empty. |
DeviceUniqueID | Uniquely identify the device. |
DeviceFirmwareVersion | The
device manufacture's firmware version, which is different from the OS
version. This value may be empty. It is recommended that the value be
parsed as a System.Version structure, but it is not mandatory. |
DeviceHardwareVersion | The
device manufacture's hardware version running on the device. This value
may be empty. It is recommended that the value be parsed as a System.Version structure, but it is not mandatory. |
DeviceTotalMemory | Device's
physical RAM size in bytes. It will be less than the actual amount of
device memory. Most devices currently shipping have either 256MB or
512MB bytes of RAM. |
ApplicationCurrentMemoryUsage | The running application's current memory usage in bytes. Developers need to track this value closely. |
ApplicationPeakMemoryUsage | The running application's peak memory usage in bytes, which is another item that developers need to track closely. |
The last two memory reporting items are very important to track.
Example 1. Sample Tick Event to Record Debug Info
void DebugMemoryInfo_Tick(object sender, EventArgs e)
{
//GC.GetTotalMemory(true);
long deviceTotalMemory =
(long)Microsoft.Phone.Info.DeviceExtendedProperties.GetValue(
"DeviceTotalMemory");
long applicationCurrentMemoryUsage =
(long)Microsoft.Phone.Info.DeviceExtendedProperties.GetValue(
"ApplicationCurrentMemoryUsage");
long applicationPeakMemoryUsage =
(long)Microsoft.Phone.Info.DeviceExtendedProperties.GetValue(
"ApplicationPeakMemoryUsage");
System.Diagnostics.Debug.WriteLine("--> " +
DateTime.Now.ToLongTimeString());
System.Diagnostics.Debug.WriteLine("--> Device Total : " +
deviceTotalMemory.ToString("#,#", CultureInfo.InvariantCulture));
System.Diagnostics.Debug.WriteLine("--> App Current : " +
applicationCurrentMemoryUsage. ToString("#,#", CultureInfo.InvariantCulture));
System.Diagnostics.Debug.WriteLine("--> App Peak : " +
applicationPeakMemoryUsage. ToString("#,#", CultureInfo.InvariantCulture));
}
|
Certification requirements
dictate that memory usage remain under 90MB, because the OS will shut
down applications that are memory hogs. Applications can temporarily go
over 90MB and not fail certification in some cases, such as if the
application is transitioning pages and one page is going out of memory
and another is loading data structures for display. In general, with
memory constrained-devices, it is important to efficiently allocate
memory to maximize performance. This is true for any mobile device
application, regardless of the operating system, and it is something
that makes mobile development a fun challenge: squeezing out every
little bit of performance possible!
In Table 1 the DeviceUniqueID
value will uniquely identify a device across all installed
applications, even if the phone is updated with a new operating system
version. This ID should not be used to identify users, because it is
tied to the device, not the user
NOTE
Accessing DeviceUniqueID in the emulator returns false for TryGetValue.
If your application can use the
DeviceUniqueID in a way that benefits the user, you should use it; be
sure, however, to mention why you use it in the application description,
so that the user understands the benefit. Otherwise, cautious users may
shy away of downloading your application.
3. System Environment Information
The System.Environment class provides the following information on the current environment via its properties:
CurrentDirectory.
HasShutdownStarted.
OSVersion (includes and Platform and Version properties. The Version has additional properties of Build, Major, Minor, and Revision).
TickCount (Since last reboot).
Version. (CLR Version).
The next section starts
with a very important topic when you are building mobile applications
that depend on data in the cloud: current network status.
4. Network Status
Mobile applications
must be thoughtful in using phone resources, such as data connectivity,
and offer the user information when using the data connection. The
Windows Phone 7 namespace Microsoft.Phone.Net.NetworkInformation provides the NetworkInterface object with the following two useful static members:
The GetIsNetworkAvailable method returns true or false. The NetworkInterface property stores a value from the Microsoft.Phone.Net.NetworkInformation.NetworkInterfaceType enumeration. Table 2 lists the common values in which most developers will be interested. You can find the full list at
http://msdn.microsoft.com/en-us/library/microsoft.phone.net.networkinformation.networkinterfacetype(VS.92).aspx
Table 2. NetworkInterfaceType Enumeration Common Values
Enumeration Value | Description |
---|
None | No interface exists to provide access to the Internet. |
Ethernet | The network interface is of type Ethernet. When connected via Zune and the PC, this is the value that is returned. |
MobileBroadbandGSM | This is the value returned when connected over a wireless GSM network. (AT&T or T-Mobile in the U.S. and most of the world.) |
MobileBraodbandCdma | This
is the value returned when connected over a wireless CDMA network.
(Verizon and Sprint in the U.S. and other regions of the world.) |
Wireless80211 | The network interface is a wireless LAN connection. |
One item to note is that, when
connected to the PC without Zune running, the network connection will
return either MobileBroadband or Wirless80211 if a connection is
available over those protocols. Zune must be running when connected to
the PC in order to have an Ethernet connection.
You may be tempted to poll
network status on a background thread, but that would not be battery
efficient. Instead, the code can subscribe to the System.Net.NetworkInformation.NetworkChange.NetworkAddressChanged static event. The System.Net.NetworkInformation namespace also includes a NetworkInterface class, so you will need to disambiguate namespaces.
In the DeviceInfo project, we add two TextBlock controls and two TextBox controls to store network availability and connection type, storing network availability status in the NetworkAvailableTextbox control, and network connection type in the NetworkConnectionTextbox control. Listing 2 has the code from the DeviceInfo project that performs network detection.
Example 2. Network Detection Method
#region Network Status Check
private void SetupNetworkStatusCheck()
{
NetworkChange.NetworkAddressChanged +=
new NetworkAddressChangedEventHandler
(NetworkChange_NetworkAddressChanged);
//Initialize values
NetworkAvailableTextBlock.Text =
PhoneNetworkApi.NetworkInterface.GetIsNetworkAvailable().ToString();
NetworkConnectionTextBlock.Text =
PhoneNetworkApi.NetworkInterface.NetworkInterfaceType.ToString();
}
void NetworkChange_NetworkAddressChanged(object sender, EventArgs e)
{
NetworkAvailableTextBlock.Text =
PhoneNetworkApi.NetworkInterface.GetIsNetworkAvailable().ToString();
NetworkConnectionTextBlock.Text =
PhoneNetworkApi.NetworkInterface.NetworkInterfaceType.ToString();
}
#endregion
|
This code requires the following two using statements for these namespaces:
using System.Net.NetworkInformation;
using PhoneNetworkApi = Microsoft.Phone.Net.NetworkInformation;
The code uses a namespace alias to disambiguate between the two namespaces for the NetworkInterface class that is present in both namespaces, though the Phone version includes the NetworkInterfaceType property. Figure 1 shows the UI displaying device and network info that we have covered in the previous sections.
5. System Tray
The system tray appears at the top of the screen in portrait mode. Figure 2 is a clip from the Windows Phone 7 Design Template file named StatusBar_PSD.psd, which shows possible status information.
The Windows Phone 7
development guidelines recommend leaving the System Tray visible within
applications, because it shows useful information without having to
force the user to exit the application. The system tray does take up a
little bit of screen real estate, so for games and media players, it
makes sense to disable the System Tray.
The system tray can be disabled on a page-by-page basis by editing the phone:PhoneApplicationPage element and setting shell:SystemTray.IsVisible to False.
This concludes our
discussion of device information. Next up is application data
persistence using isolated storage on Windows Phone 7.
6. Marketplace Status and Trial Mode
Windows Phone 7 supports building a single application that includes both trial and full functionality. The Microsoft.Phone.Marketplace.LicenseInformation class provides has one method named IsTrial() that the application can use to determine if the application has been fully purchased or is in trial mode.
As a developer, you get to
determine what is the right trial experience for your application. For a
game, it might be a certain number of tries or just the first level.
For an application, it might be filtering to a subset of information,
display advertising, or lack of personalization.
Application developers in Silverlight can use the MarketplaceDetailTask class to display the purchase experience. The MarketplaceDetailTask is discussed below in the Tasks section covering launchers and choosers.
For XNA Game Studio developers, the Microsoft.Xna.Framework.GamerServices.Guide class has a method named IsTrialMode to get current license information. Developers call Guide.ShowMarketplace to display the purchase experience. The Guide.SimulateTrialMode property allows developer to test their game under trial mode conditions.
Trial mode is a great way
to encourage end users to try out your application, enjoy it, and
purchase the full version. If you plan to sell your application,
implement and test trial mode.
|
|
Silverlight developers may
be wondering how they can simulate trial mode. The good news is that
Silverlight developers can also use the Microsoft.Xna.Framework.GamerServices.Guide class and the SimulateTrialMode property. Set it to true to permit testing trial mode functionality.
When testing trial mode by setting SimulateTrialMode to true, a call to Guide.IsTrialMode returns the current value of SimulateTrialMode. Calling Guide.ShowMarketplace simulates making a purchase.
You must set SimulateTrialMode to false in release code. Place the code that sets it to true in #if DEBUG to ensure it is not available in a released application submitted to Marketplace.
|
|
In this
section, we covered how to identify users, the device, network status,
and application trial mode status for Windows Phone 7. In the next
section, we move to the next major topic of settings and data storage in
isolated storage.