How to adjust data usage using the Data Sense API for Windows Phone 8

[ This article is for Windows Phone 8 developers. If you’re developing for Windows 10, see the latest documentation. ]

You can code your app to reduce data usage when a user is close to their data limit, to discontinue data usage when the user is over their limit, or to postpone tasks that transfer data until a Wi-Fi connection is available.

Through the Data Sense feature, a user can specify the limits of their data plans. Then, Data Sense monitors data usage in relation to the user-specified limits. With this information, your app can help users to save money by adjusting its data usage.

Important Note:

Installing the Data Sense app and Tile on phones is optional for mobile operators. As a result, users of your app might not have the Data Sense app on their phones. Without the app, users can't enter their data limits.

When users’ data limits are unknown, you can still use the Data Sense API to determine whether they're using a Wi-Fi connection, or roaming. However you can't use the Data Sense API to determine whether they're approaching their data limit, or over their data limit.

This topic contains the following sections.

Required capability

An app that uses the Data Sense API requires the ID_CAP_NETWORKING capability. You indicate this requirement in the app manifest file. For more info, see App capabilities and hardware requirements for Windows Phone 8.

When to check a user’s data usage

Design your app to check a user’s data usage in your app at the following times:

  1. When the app starts—that is, when the Launching event occurs.

  2. When the NetworkInformation..::.NetworkStatusChanged event occurs. This event occurs under the following conditions:

    • When the type of connection changes between cellular and Wi-Fi.

    • When the user enters or leaves the roaming state.

    • When ApproachingDataLimit or OverDataLimit becomes true.

  3. When the app is reactivated after a pause caused by deactivation or tombstoning—that is, when the Activated event occurs.

  4. Optionally, before a long-running operation that transfers a large amount of data.

How to check a user’s data usage

You typically use the following classes, methods, and properties from the Windows.Networking.Connectivity namespace to determine whether your app should reduce, discontinue, or postpone data usage. The code sample in this topic demonstrates how to use these objects.

  1. Retrieve the ConnectionProfile by calling the static GetInternetConnectionProfile method of the NetworkInformation class.

  2. Check the IanaInterfaceType property of the NetworkAdapter associated with the current ConnectionProfile.

    If the phone is using a free Wi-Fi connection, the app doesn’t need to limit data usage. Otherwise, continue with the next step.

  3. Check the NetworkCostType property of the ConnectionCost class that is associated with the current ConnectionProfile class by calling its GetConnectionCost method. The available values are the members of the NetworkCostType enumeration, as follows:

    • Unknown

    • Unrestricted

    • Fixed

    • Variable

    If the user’s data limit is Unrestricted, the app doesn’t need to limit data usage. Otherwise, continue with the next step.

  4. Check the other three properties of the ConnectionCost class associated with the current ConnectionProfile class to determine whether one of the following properties is true for the user’s data limit.

    If one of these values is true, your app can reduce or eliminate data usage.

    If the user has not yet specified a data limit and the NetworkCostType is Unknown, the value of ApproachingDataLimit and OverDataLimit is false. You have to choose the best behavior for your app when the cost of data usage is unknown.

    The Roaming property returns an accurate value even when the NetworkCostType is Unknown.

How to reduce the user’s cost of data

The following table lists suggestions for how an app can adjust its data usage to reduce the user’s cost of data:

NetworkCostType

ConnectionCost

Responsible data usage

Examples

Unrestricted

Not applicable.

No restrictions.

Stream high-definition video.

Download high-resolution pictures.

Retrieve email attachments.

Fixed or Variable

All three of the following properties are false.

No restrictions.

Stream high-definition video.

Download high-resolution pictures.

Retrieve email attachments.

Fixed or Variable

or

Unknown

ApproachingDataLimit is true, when NetworkCostType is Fixed or Variable.

Not applicable when NetworkCostType is Unknown.

Transfer less data.

Provide option to override.

Stream lower-quality video.

Download low-resolution pictures.

Retrieve only email headers.

Postpone tasks that transfer data.

Fixed or Variable

OverDataLimit or Roaming is true.

Don’t transfer data.

Provide option to override.

Stop downloading video.

Stop downloading pictures.

Do not retrieve email.

Postpone tasks that transfer data.

When you write your app to reduce, discontinue, or postpone data usage, we recommend that you provide the user with an option to override the reduced usage levels suggested here. However, a recurring prompt may not be the best solution. To minimize interruptions for the user, you can create an app-level setting that gives the user the option to bypass recurring prompts. For example, you could create a Prompt to override reduced data usage setting with the following possible values: Always override, Prompt to override, and Never override.

Note

You can’t use the Simulation Dashboard to test your Data Sense code by changing the network type from cellular to Wi-Fi or reverse. The Simulation Dashboard does not change the values of the properties that the Data Sense API uses, and which we describe here. For more information about network simulation in the Simulation Dashboard, see How to simulate a low-bandwidth connection or poor signal for Windows Phone 8.

When a Wi-Fi connection for which the phone has connection information becomes available, the phone automatically switches from a cellular connection to the Wi-Fi connection. You don’t need to write code to disconnect and reconnect when a Wi-Fi connection becomes available.

Example

The following code sample demonstrates how to adjust data usage based on a user-specified data limit.

using Windows.Networking.Connectivity;
…

namespace DataSenseSample
{
    public partial class MainPage : PhoneApplicationPage
    {

        bool m_bDoNotSendData = false;
        bool m_bSendLowResolutionImage = false;

        private const int IANA_INTERFACE_TYPE_WIFI = 71;

        NetworkStatusChangedEventHandler networkStatusCallback;

        // Constructor.
        public MainPage()
        {
            InitializeComponent();

            // Handle the NetworkStatusChanged event.
            networkStatusCallback = new NetworkStatusChangedEventHandler(OnNetworkStatusChange);
            UpdateNetworkInformation();

        }

        void UpdateNetworkInformation()
        {
            // Get current Internet Connection Profile.
            ConnectionProfile internetConnectionProfile = Windows.Networking.Connectivity.NetworkInformation.GetInternetConnectionProfile();
           
            // Check the connection details.
            if (internetConnectionProfile.NetworkAdapter.IanaInterfaceType != IANA_INTERFACE_TYPE_WIFI)
            {
                // Connection is not a Wi-Fi connection. 
                if (internetConnectionProfile.GetConnectionCost().Roaming)
                {
                    // User is roaming. Don't send data out.
                    m_bDoNotSendData = true;
                }

                if (internetConnectionProfile.GetConnectionCost().ApproachingDataLimit)
                {
                    // User is approaching data limit. Send low-resolution images.
                    m_bSendLowResolutionImage = true;
                }

                if (internetConnectionProfile.GetConnectionCost().OverDataLimit)
                {
                    // User is over data limit. Don't send data out.
                    m_bDoNotSendData = true;
                }
            }
            else
            {   
                //Connection is a Wi-Fi connection. Data restrictions are not necessary.                        
                m_bDoNotSendData = false;
                m_bSendLowResolutionImage = false;
            }

            // Optionally, report the current values in a TextBox control.
            string cost = string.Empty;
            switch (internetConnectionProfile.GetConnectionCost().NetworkCostType)
            {
                case NetworkCostType.Unrestricted:
                    cost += "Cost: Unrestricted";
                    break;
                case NetworkCostType.Fixed:
                    cost += "Cost: Fixed";
                    break;
                case NetworkCostType.Variable:
                    cost += "Cost: Variable";
                    break;
                case NetworkCostType.Unknown:
                    cost += "Cost: Unknown";
                    break;
                default:
                    cost += "Cost: Error";
                    break;
            }
            cost += "\n";
            cost += "Roaming: " + internetConnectionProfile.GetConnectionCost().Roaming + "\n";
            cost += "Over Data Limit: " + internetConnectionProfile.GetConnectionCost().OverDataLimit + "\n";
            cost += "Approaching Data Limit : " + internetConnectionProfile.GetConnectionCost().ApproachingDataLimit + "\n";

            NetworkStatus.Text = cost;
        }

        async void OnNetworkStatusChange(object sender)
        {
            UpdateNetworkInformation();
        }


    }
}