Lumia SensorCore SDK: New Features for Mobile Application Development. Part 2: Creating an Application



    Good day, everyone!

    In a previous article, we reviewed the Lumia SensorCore SDK and its components, which allow you to create applications that track user activity in minimum power mode.

    In this article, we will look at the practical use of the SensorCore SDK to create an application that sends notifications according to the location of the device. We will discuss recommendations for working with the new SDK, and see how to generate and use dummy data, as well as API simulators.

    As an example of using the SensorCore SDK , let's take the idea of ​​an application that sends a notification depending on the location of the device . The Place Monitor API tool is great for this purpose .

    As described in a previous article, in order to use applications with the SensoreCore SDK, the device must have certain software and hardware characteristics. This condition imposes additional requirements on such applications. For example, you need to develop scenarios for handling situations when the phone does not meet the relevant requirements, but the application is installed on it:



    In another situation, when the collection of necessary information is disabled by the user, you should provide quick access to connect the settings (Fig. 1-2), as well as a scenario in which the user refuses to connect them (Fig. 3) - for example, the application stops correctly :



    Next, let's look at an example of creating an application using the best development practices using the SensorCore SDK .

    Create an application


    There are some general guidelines on how to use SensorCore in order to ensure the stability and compatibility of the application with the device on which it will be installed.

    Below are examples of initialization, error handling, and application lifecycle management:

    1. Create a Blank App (Windows Phone) project in C # using Visual Studio 2013 (Update 3).
    2. We connect SensorCore SDK to the project: Tools-> NuGet Package Manager-> Manage NuGet Packages Click Install for all components. Thus, links to Lumia libraries were added to the project . Sense , Lumia. Sense. Testing and Microsoft Visual C ++ 2013 Runtime Package for Windows Phone .






    3. To access the API, you must declare the SensorCore HID device and the ability to access it in the application manifest.

      Installing the SDK adds these features to Package.appxmanifest automatically:

      <DeviceCapabilityName="location" /><m2:DeviceCapabilityName="humaninterfacedevice"><m2:DeviceId="vidpid:0421 0716"><m2:FunctionType="usage:ffaa 0001" /><m2:FunctionType="usage:ffee 0001" /><m2:FunctionType="usage:ffee 0002" /><m2:FunctionType="usage:ffee 0003" /><m2:FunctionType="usage:ffee 0004" /></m2:Device></m2:DeviceCapability>

    4. In order for the SDK to work correctly, you must switch the platform to x86 in the Configuration Manager: Build -> Configuration manager It should be noted that when testing the application on the device, the Active solution platform should be set to ARM .




    5. To use the SensoreCore SDK tools, we will connect the following libraries:

      using Windows.UI.Popups;
      using System.Threading.Tasks;
      using Lumia.Sense;
      using Lumia.Sense.Testing;
      


    Initializing SensoreCore


    It is not always possible or convenient to work with the actual SensorCore API when developing your application: you can test specific application logic or user interface with predefined data, or if you run your application in the Windows Phone emulator, the actual SensorCore interfaces are not available at all. In such cases, you must use the SensorCore simulator .

    Replacing the actual SensorCore APIs with a simulator is easy, just add to the class identifier “Simulator”:

    private PlaceMonitor _placeMonitor;=> private PlaceMonitorSimulator _placeMonitor;
    

    But to make it easier to switch between the actual class and the simulator class, it is most convenient to use an alias for the class , and in the project, access it with the keyword Monitor.
    For example:

    //using Monitor = Lumia.Sense.PlaceMonitor;using Monitor = Lumia.Sense.Testing.PlaceMonitorSimulator;
    

    Initialization of necessary equipment support


    Since the operation of the Lumia SensorCore SDK is based on the hardware capabilities of the phone that not all devices possess, the first thing to consider when developing is to check whether the device supports the equipment necessary for SensorCore .

    If there is a scenario for the application in which the use of the SensorCore SDK is not necessary, then it would be nice to adjust the visibility of the UI controls accordingly.

    if (await Monitor.IsSupportedAsync())
    

    Note that while the PlaceMonitorSimulator class is used, the property is not supported, and at this stage the corresponding code must be commented out , however, when using the real API in the application, it should be activated again:

    //if (await Monitor.IsSupportedAsync())
                    {
                        // Init SensorCoreif (await CallSensorcoreApiAsync(async () => { monitor = await Monitor.GetDefaultAsync(); }))
                        {
                            Debug.WriteLine("PlaceMonitor initialized.");
                            // Update list of known places
                            UpdateKnownPlacesAsync();
                            HomeButton.IsEnabled = true;
                            WorkButton.IsEnabled = true;
                            FrequentButton.IsEnabled = true;
                            CurrentButton.IsEnabled = true;
                        }
                        else
                        {
                            Application.Current.Exit();
                        }
                        // Focus on home
                        OnHomeClicked(null, null);
                    }
    /*                else
                    {
                        MessageDialog dialog;
                        dialog = new MessageDialog("Your device doesn't support Motion Data. Some functionality will be disabled", "Information");
                        dialog.Commands.Add(new UICommand("Ok"));
                        await dialog.ShowAsync();
                        HomeButton.IsEnabled = false;
                        WorkButton.IsEnabled = false;
                        FrequentButton.IsEnabled = false;
                    }*/


    Secure Call Lumia SensorCore SDK


    When calling the API, it is important to verify that the required settings ( Location data / Motion data ) are enabled and that no exception will occur.
    To do this, we use a wrapper that needs to be defined when calling the SensorCore SDK and which takes care of such situations:

    privateasync Task<bool> CallSensorcoreApiAsync(Func<Task> action)
            {
                Exception failure = null;
                try
                {
                    await action();
                }
                catch (Exception e)
                {
                    failure = e;
                }
                if (failure != null)
                {
                    switch (SenseHelper.GetSenseError(failure.HResult))
                    {
                        case SenseError.LocationDisabled:
                            MessageDialog dialog = new MessageDialog("Location has been disabled. Do you want to open Location settings now?", "Information");
                            dialog.Commands.Add(new UICommand("Yes", async cmd => await SenseHelper.LaunchLocationSettingsAsync()));
                            dialog.Commands.Add(new UICommand("No"));
                            await dialog.ShowAsync();
                            new System.Threading.ManualResetEvent(false).WaitOne(500);
                            returnfalse;
                        case SenseError.SenseDisabled:
                            dialog = new MessageDialog("Motion data has been disabled. Do you want to open Motion data settings now?", "Information");
                            dialog.Commands.Add(new UICommand("Yes", async cmd => await SenseHelper.LaunchSenseSettingsAsync()));
                            dialog.Commands.Add(new UICommand("No"));
                            await dialog.ShowAsync();
                            new System.Threading.ManualResetEvent(false).WaitOne(500);
                            returnfalse;
                        default:
                            dialog = new MessageDialog("Failure: " + SenseHelper.GetSenseError(failure.HResult), "");
                            await dialog.ShowAsync();
                            returnfalse;
                    }
                }
                returntrue;
            }
    

    Now the monitor.CallSensorcoreApiAsync wrapper for accessing the SensorCore SDK is ready, so that the SDK call becomes safe.

    Before using any API SensorCore SDK, you must initialize it by calling GetDefaultAsync . Initialization can be performed using the shell described above:

    if (await CallSensorcoreApiAsync(async () => { monitor = await Monitor.GetDefaultAsync(); }))
    

    If the call to SensorCore APIs fails, the application will stop at this point.

    Activation and deactivation of sensors


    In Windows XAML applications, the management model is different from Silverlight applications, so connecting and disconnecting sensors is handled differently.

    Add a VisibilityChanged event handler , where we will activate and deactivate PlaceMonitor when the application is sent to the background or when it is in focus again.

    Windows XAML:

    Window.Current.VisibilityChanged += async (oo, ee) =>
                {
                    if (monitor != null) {
                        if (!ee.Visible)
                        {
                            await CallSensorcoreApiAsync(async () => { await monitor.DeactivateAsync(); });
                        }
                        else
                        {
                            await CallSensorcoreApiAsync(async () => { await monitor.ActivateAsync(); });
                        } }
                };
    

    For Silverlight applications, do the following:

    protectedasyncoverridevoidOnNavigatedTo(NavigationEventArgs e) 
    {
        if (monitor == null)
        {
            await Initialize();
        }
        await monitor.ActivateAsync(); 
    }
    protectedoverrideasyncvoidOnNavigatingFrom(NavigatingCancelEventArgs e) {
        await monitor.DeactivateAsync(); 
    } 
    


    Error processing


    All errors of the Lumia SensorCore SDK cause exceptions, detailed information about which can be obtained using the SenseHelper.GetSenseError () function .

    As mentioned above, applications using the SensorCore SDK can also be installed on devices that do not support the SDK functionality.
    In such an application, a scenario should be described for the case when none of the data acquisition sensors is available . If the application cannot function without the SensorCore SDK, this feature should be specified in the application description in the Windows Phone Store .

    Testing Data


    Each dummy API by default has data for processing and playback, and is also able to accept recorded data as input.

    To model your own sensor data, you can use the SenseRecorder class:

    PlaceMonitor monitor = await PlaceMonitor.GetDefaultAsync();
    SenseRecorder recorder = new SenseRecorder(monitor);
    await recorder.StartAsync();
    // ... запись данных ...await recorder.StopAsync();
    await recorder.GetRecording().SaveAsync(); 
    

    SenseRecording.SaveAsync () starts viewing a document to display the recorded data and offers to save it in the Documents folder on the phone. You can get the saved file from this folder by connecting the phone to the computer using Explorer.

    Next, we associate the record with the project, loading it using the SenseRecording.LoadFromFileAsync () function , and then transfer the data to the simulator with the GetDefaultAsync () function:

    SenseRecording recording = await SenseRecording.LoadFromFileAsync("myData.txt");
    PlaceMonitorSimulator simulator = await PlaceMonitorSimulator.GetDefaultAsync(recording); 
    

    By default, the recording is configured so that the first event trigger is logged immediately after launch. If it is necessary to define these records as fixed earlier or later, then for the GetDefaultAsync () function you can set your own time for the simulator to start working:

    PlaceMonitorSimulator simulator = await PlaceMonitorSimulator.GetDefaultAsync(recording, DateTime.Now - TimeSpan.FromDays(2)); 
    

    The simulator reproduces the recorded data indefinitely, so that the recording can be used as a two-day history, or vice versa, as data that will be received only two days after the application starts.

    It is worth noting that when the application switches to the background, the recording of test data stops and can continue only when activated, since the SenseRecording class does not work in the background.

    Background task


    In the case of realizing the idea of ​​this application, it is necessary to use a background task, since the notification from the application that “the user has returned home” should occur when entering the geofence of a frequently visited place, and then when the application is not running.

    To create such a task, there is a standard algorithm:
    • Creating a background task;
    • Declaring it in the application manifest;
    • Registration of the background task in the application.

    Let's

    move on to its implementation: Add a new Windows Runtime Component project to the solution : Rename the automatically generated Class1.cs to GeofenceBackgroundTask and inherit the IBackgroundTask interface. Do not forget to connect the appropriate namespace: using Windows.ApplicationModel.Background Add the Run method necessary for any background task to this class:









    publicvoidRun(IBackgroundTaskInstance taskInstance)
            {
          // отправление уведомленияvar toastTemplate = ToastTemplateType.ToastText02;
                var toastXML = ToastNotificationManager.GetTemplateContent(toastTemplate);
                var textElements = toastXML.GetElementsByTagName("text");
                textElements[0].AppendChild(toastXML.CreateTextNode("Welcome again!"));
                var toast = new ToastNotification(toastXML);
                ToastNotificationManager.CreateToastNotifier().Show(toast);
            }
    

    Add a link to the background task project: right - click -> References-> Add Reference. Select and click OK. Declare a background task in Package.appxmanifest: On the Declarations-> Available declarations: Background Task-> Add Note the Properties has: the Location , Field Entry point fill in the name of the class with the namespace indication: BackgroundTask.GeofenceBackgroundTask. Add the following method to register the background task:















    publicstaticasync Task RegisterBackgroundTask()
            {
                try
                {
                    var backgroundAccessStatus = await BackgroundExecutionManager.RequestAccessAsync();
                    var geofenceTaskBuilder = new BackgroundTaskBuilder()
                    {
                        Name = "GeofenceBackgroundTask",
                        TaskEntryPoint = "BackgroundTask.GeofenceBackgroundTask"
                    };
                    var trigger = new LocationTrigger(LocationTriggerType.Geofence);
                    geofenceTaskBuilder.SetTrigger(trigger);
                    geofenceTaskBuilder.Register();
                }
                catch (Exception e)
                {
                    Debug.WriteLine(e);
                }
            }
    

    We register the task, for this we call the previous method in the application:

    await RegisterBackgroundTask();
    

    As a result, we receive a notification from the application in the background when entering the geo-zone of a frequently visited place:



    Conclusion


    In addition to the existing capabilities in Windows Phone 8.1, with the Lumia SensorCore SDK developers get advanced functionality for creating applications in which users will be able to receive and analyze information about their life activities, while consuming the minimum amount of phone’s energy resources .

    Developers can apply the experience of using new APIs from existing examples of real applications, which are also available for download in the Windows Phone Store. And also using the detailed documentation for the new SDK.

    useful links


    Lumia SensorCore SDK:


    Microsoft Virtual Academy (MVA) Training Courses
    Windows Development Center
    Download Free or Trial Visual Studio 2013
    Lumia SensorCore SDK: Part 1. Overview

    Also popular now: