Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
miltonc
Product and Topic Expert
Product and Topic Expert
0 Kudos

Note:  The code for the sample application is now published.

In this blog, I will be talking about the Usage Collection library.  The primary objective of this library of course, is to collect application usage statistics.  The SAP Mobile Platform SDK (hereinafter referred to as “SMP SDK” or “SDK”) automatically logs some predefined events and metrics.  In addition, you can also log custom defined timers, events and measurements.  Overall, this library gives IT administrators the ability to view and analyze application usage statistics.  Usage Collection works only with HANA Cloud Platform Mobile Services (hereinafter referred to as “HCPms”) and not the On-Premise SMP Server.

Lifecycle of Windows Store application

The Usage Collection library is equipped to send certain metrics to HCPms when the application starts.  It is also necessary to stop the Usage Collection library from collecting metrics when the application is closed.  For this reason, it is very important to understand the lifecycle of a Windows Store application.

NotRunning

An application can be in the NotRunning state if

  1. Application has never been launched
  2. Application was running, but then crashed
  3. Application was suspended and later terminated by system (due to memory resources)

Running

An application can be in the Running state if

  1. Once the application completes activation (UI ready to be displayed to user)

Suspended

An application can be in the suspended state if

  1. User moves app to background (if user doesn’t switch back soon, Windows suspends the app)
  2. Device enters low power state

If application does not return from suspended state within 5 seconds, Windows could terminate the app anytime for low resources.

Understanding user session

In the context of the mobile application built using SMP SDK, the user session can be roughly characterized as the time interval between the application in a running state and the application in a suspended state.  Running state (in the context of Usage Collection) is defined as the application in a running state and the user logged in (For example, the application is not in the running state if the logon screen is being displayed).

The idea is for the developer to let the application know using the Usage Collection library that the application is about to start and about to be suspended.  This can be accomplished using the ApplicationWillEnterForeground and ApplicationWillEnterBackground asynchronous methods of the Usage Collection class.  A user session id is generated and appended to each record that is recorded during that particular session.  When the session is started by calling ApplicationWillEnterForeground, all previously collected usage statistics are automatically sent to HCPms.  In the event usage statistics could not be sent for some unforeseen reason when a session starts, then they are resent in subsequent session restarts along with additional usage statistics collected up until that point.

How to initialize the Usage Collection library and start the user session?

Initializing the Usage Collection library takes 2 parameters and is done asynchronously.   Once the Usage Collection library is initialized, you also want to call ApplicationWillEnterForeground to signal that the user session has started.  This can be called when the user logs in successfully in the LogonCompleted event handler.

await SAP.Usage.Usage.InitUsageAsync(Globals.UploadUrl, Globals.HttpClient);

// notify the Usage that the app goes to foreground

SAP.Usage.Usage.ApplicationWillEnterForeground();

Note that the application can also resume from a suspended mode.  If the datavault timeout has not expired, then the application will not display the logon screen and hence LogonCompleted event handler will not be fired. So it is also necessary to call the ApplicationWillEnterForeground method when the application resumes from a suspended state.  This can be done in the OnResuming event handler.

private void OnResuming(object sender, object e)

{

   // notify the Usage that the app goes to foreground

   Usage.ApplicationWillEnterForeground();

}

The InitUsageAsync method takes 2 parameters.  The first parameter is the URL where you want to upload the usage statistics.  Note that Usage Collection only works with HCPms. Please refer to the HCPms documentation for URL to upload the usage statistics.

private static string uploadUrl = string.Empty;

public static string UploadUrl

{

   get

   {

      return "URL to upload.  Refer to HCPms documentation";

   }

}

The second parameter is the SAP.Net.Http.HttpClient.  The SAP.Net.Http.HttpClient is SAP’s implementation of a class for sending HTTP requests and receiving HTTP responses from a resource identified by a URI. In addition, the SAP.Net.Http.HttpClient class provides several additional functionalities over the base System.Net.Http.HttpClient class.

private static SAP.Net.Http.HttpClient httpClient = new SAP.Net.Http.HttpClient();

public static SAP.Net.Http.HttpClient HttpClient

{

   get

   {

      var applicationSettings = LogonCore.ApplicationSettings;

        

      SAP.Logon.Core.Settings.IReadOnlyProperty baseUrlObject = null;

      applicationSettings.TryGetValue("BaseUrl", out baseUrlObject);

      Uri baseUrl = (Uri)baseUrlObject;

      SAP.Logon.Core.Settings.IReadOnlyProperty cookieObject = null;

      applicationSettings.TryGetValue("Cookies", out cookieObject);

      string cookieString = cookieObject == null ? null : cookieObject.ToString();

      if ((cookieString != null) && (baseUrl != null))

httpClient.SetInitialCookies(cookieString, baseUrl);

               

httpClient.DefaultRequestHeaders.TryAddWithoutValidation("X-SMP-APPCID", applicationSettings.ApplicationConnectionId);

      return httpClient;

   }

}

How can I end the user session?

The user session ends when the application enters the suspended state.  In Windows, the OnSuspending event is fired when application execution is being suspended.  This is a good place to end the user session.  This is done by calling ApplicationWillEnterBackgroundAsync asynchronously.

private async void OnSuspending(object sender, SuspendingEventArgs e)

{

   var deferral = e.SuspendingOperation.GetDeferral();

   //TODO: Save application state and stop any background activity

   deferral.Complete();

   // notify the Usage that the app goes to background

   await Usage.ApplicationWillEnterBackgroundAsync();

}

Collecting Device specific info

Device specific information can be collected using the Usage Collection library.  This can be accomplished by querying the DeviceInformation property of the Usage class. 

Usage.DeviceInformation.Application

Usage.DeviceInformation.AppVersion

Usage.DeviceInformation.Model

Usage.DeviceInformation.Platform

Usage.DeviceInformation.SystemVersion

UsageReachability.CurrentReachabilityStatus

Timing events and logging key events

Events can be timed using the Usage Collection library.  The timer object allows you to measure the duration of an application operation. The duration is logged with the timestamp of the event and a key value that can be used for filtering analytics.

The following code snippet shows how to use the timer object.

Usage.TimeStart ("myTimer");

var downloadedFile = await GetHugeFileAsync();

// stops the timer. The last 2 parameters are optional

await Usage.TimeEndAsync("myTimer", new Dictionary<string, string>() { { "customKey", "customVal" } }, "customType");

There is yet another way to use the timer object.

var timerInstance = Usage.MakeTimer("myTimer");

timerInstance.StartTimer();

var downloadedFile = await GetHugeFileAsync();

timerInstance.StopTimer();

Logging key events can be done asynchronously by calling the LogAsync method.

// adds a log entry into the report. The last 2 parameters are optional

await Usage.LogAsync("logKey", new Dictionary<string, string>() { { "testKey", "testValue" } }, "testType");

All of these usage statistics collected will be automatically sent to HCPms without any further coding from the developer.  An example of a sample record generated by the Usage Collection library that will be posted to HCPms is as follows…

{

       "type":"timer",

       "key":"DownloadTimer",

       "info":{

              "start":"2014-10-27T09:05:39.215Z",

              "duration":"10.6092"},

       "appSessionId":"",

       "userSessionId":"4dbcb6fa-7608-4430-bade-128f41a2f614",

       "timestamp":"2014-10-27T09:05:49.825Z"

}

  This concludes my blog on Usage Collection library.  See you all at the next blog.