Settings

The settings plugin is used to exchange settings between an SMP 3.0 or HCPms server and a Kapsel application. The available settings can be seen in a browser via the URL https://localhost/odata/applications/v4/com.kapsel.gs/$metadata.

The following two samples will be used to demonstrate a settings exchange using REST API’s and then an example using the Settings plugin.

Settings using XMLHttpRequest Object
Settings Exchange using the Settings Plugin

Settings using XMLHttpRequest Object

The following example uses the JavaScript XMLHttpRequest object to communicate with an SMP or HCPms server. In addition to performing a registration and unregister, this example shows the result of requesting an application’s settings and demonstrates how one setting can be set. The metadata returned from pressing Show Settings MetaData can be used to see the list of available settings that can be read and updated.

  • Create the following file and copy the below contents into it.
    C:\temp\register.html
    <!DOCTYPE html>
    <html>
        <head>
            <!--<meta http-equiv="Content-Security-Policy" content="default-src 'self' http://localhost:8080 'unsafe-inline' data: gap: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *">-->
            <script>
                window.onerror = onError;
                var appCID = window.localStorage.getItem("appcid");
                var connectionData = {
                    DeviceType : "Windows" // Windows, iOS, Android etc      
                };
                var settingsData = {
                    DevicePhoneNumber : "123 456 7899" // one of the properties listed as sup:ReadOnly="false"
                };
    
                var host = "localhost"; //note if this value changes, also change Content Security Policy (the meta tag on line 4)
                var userName = "i82XXXX";
                var password = "XXXXXXX";
                var baseAppIDStr = "/odata/applications/latest/com.kapsel.gs/";
    
                function onError(msg, url, line) {
                    var idx = url.lastIndexOf("/");
                    var file = "unknown";
                    if (idx > -1) {
                        file = url.substring(idx + 1);
                    }
                    alert("An error occurred in " + file + " (at line # " + line + "): " + msg);
                    return false; //suppressErrorAlert;
                }
    
                function onLoad() {
                    var userEl = document.getElementById("user");
                    var passwordEl = document.getElementById("password");
                    var hostEl = document.getElementById("host");       
                    userEl.value = userName;
                    passwordEl.value = password;
                    hostEl.value = host;         
                }
    
                function getSMPURL() {
                    return "http://" + document.getElementById("host").value + ":8080";
                }
    
                function getUserName() {
                    return document.getElementById("user").value;
                }
    
                function getPassword() {
                    return document.getElementById("password").value;
                }
    
                function register() {
                    if (appCID) {
                        alert("Already Registered");
                        return;
                    }
                    sUrl = getSMPURL() + baseAppIDStr + "Connections"; 
    
                    var xmlhttp = new XMLHttpRequest();
                    xmlhttp.onreadystatechange = function() {
                        console.log(xmlhttp.responseText);
                        if (xmlhttp.readyState == 4) {
                            if (xmlhttp.status == 201) {
                                var startStr = "ApplicationConnectionId>";
                                var start = xmlhttp.responseText.indexOf(startStr);
                                if (start != -1) {
                                    var end = xmlhttp.responseText.indexOf("</d:ApplicationConnectionId");
                                    appCID = xmlhttp.responseText.substring(start + startStr.length, end);
                                    window.localStorage.setItem("appcid", appCID);
                                    alert("Registered Successfully");
                                }
                            }
                            else {
                                alert("Registration failed with a result code of " + xmlhttp.status);
                            }
                        }
    
                    }
                    
                    xmlhttp.open("POST", sUrl, true);
                    xmlhttp.setRequestHeader("Authorization", "Basic " + btoa(getUserName() + ":" + getPassword()));
                    xmlhttp.setRequestHeader("Accept", "application/atom+xml");
                    xmlhttp.setRequestHeader("Content-Type", "application/json");
                    xmlhttp.send(JSON.stringify(connectionData));
                }
    
                function unRegister() {
                    if (!appCID) {
                        alert("Not Registered");
                        return;
                    }
                    sUrl = getSMPURL()   + baseAppIDStr + "Connections('" + appCID + "')";
                    appCID = "";
                    window.localStorage.setItem("appcid", "");
                    var xmlhttp = new XMLHttpRequest();
                    xmlhttp.onreadystatechange = function() {
                        if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
                            alert("Successfully Unregistered");
                        }
                    }
                    xmlhttp.open("DELETE", sUrl, true);
                    xmlhttp.setRequestHeader("Authorization", "Basic " + btoa(getUserName() + ":" + getPassword()));
                    xmlhttp.send();
                }
    
                function getSettingsMetaData() {
                    var xmlhttp = new XMLHttpRequest();
                    xmlhttp.onreadystatechange = function() {
                        if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
                            console.log(xmlhttp.responseText);
                            alert("Check the WebInsepctor console for the settings metadata details or the Network > Preview tab.");
                        }
                    }
                    sUrl = getSMPURL() + baseAppIDStr + "$metadata";  
                    xmlhttp.open("GET", sUrl, true);
                    xmlhttp.setRequestHeader("Authorization", "Basic " + btoa(getUserName() + ":" + getPassword()));
                    xmlhttp.setRequestHeader("Accept", "application/xml");  //setting this so it is easier to view response in Network > Preview tab.
                    xmlhttp.send();
                }
    
                function getSettings() {
                    if (!appCID) {
                        alert("Must be registered");
                        return;
                    }
                    var xmlhttp = new XMLHttpRequest();
                    xmlhttp.onreadystatechange = function() {
                        if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
                            console.log(xmlhttp.responseText);
                            alert("Check the WebInsepctor console for the settings details or the Network > Preview tab.");
                        }
                    }
                    sUrl = getSMPURL() + baseAppIDStr +"Connections('" + appCID + "')";
                    xmlhttp.open("GET", sUrl, true);
                    xmlhttp.setRequestHeader("Authorization", "Basic " + btoa(getUserName() + ":" + getPassword()));
                    xmlhttp.setRequestHeader("Accept", "application/json");  //setting this so it is easier to view response in Network > Preview tab.
                    xmlhttp.send();
                }
    
                function updateSettings() {
                    if (!appCID) {
                        alert("Must be registered");
                        return;
                    }
                    var xmlhttp = new XMLHttpRequest();
                    xmlhttp.onreadystatechange = function() {
                        if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
                            console.log(xmlhttp.responseText);
                            alert("Setting DevicePhoneNumber updated.  Call GetSettings to see updated value");
                        }
                    }
                    sUrl = getSMPURL() + baseAppIDStr + "Connections('" + appCID + "')";
                    xmlhttp.open("POST", sUrl, true);
                    xmlhttp.setRequestHeader("Authorization", "Basic " + btoa(getUserName() + ":" + getPassword()));
                    xmlhttp.setRequestHeader("X-HTTP-METHOD", "MERGE");
                    xmlhttp.setRequestHeader("Content-Type", "application/json");
                    xmlhttp.send(JSON.stringify(settingsData));
                }
    
            </script>
            
        </head>
        <body onload="onLoad()">
            <h1>Settings Exchange Sample</h1>
            SMP 3.0 Host: <input type="text" id="host" value=""><br>
            User ID: <input type="text" id="user" value=""><br>
            Password: <input type="text" id="password" value=""><br>
            <button id="register" onclick="register()">Register</button>
            <button id="unregister" onclick="unRegister()">Unregister</button>
            <button id="getsettingsMetaData" onclick="getSettingsMetaData()">Get Settings MetaData</button>
            <button id="getsettings" onclick="getSettings()">Get Settings</button>
            <button id="updateSettings" onclick="updateSettings()">Update Settings</button>
        </body>
    </html>

     

  • In register.html, modify the host to be IP address or host name of your SMP or HCPms server. localhost can be used if the SMP server is running on the same machine as browser.Also, modify the userName and password variables to match your credentials used to access the OData service (sapes4).
  • To enable register.html to be loaded directly from the file system and to make requests to another computer, open an instance of Chrome that has web security disabled.
    start "" "c:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --user-data-dir="c:/temp/_chrome_dev" --disable-web-security
    

    Notice that when Chrome starts, it indicates the –disable-web-security flag is in effect.

  • If the following error is shown when opening the page, it can be resolved by following the steps below.
    register.html:7 Uncaught DOMException: Failed to read the 'localStorage' property from 'Window': Access is denied for this document.
    

    This is fixed by unchecking ‘Block third-party cookies and site data’ in Settings > Show advanced Settings > Privacy > Content Settings

  • Press Register to register with the SMP or HCPms server.
    Press Get Settings MetaData to show the metadata document for this app (com.mycompany.logon).
    Note the XML can be viewed either in the WebInspector console or in the network preview tab as shown below. For additional help with debugging see the Debugging Appendix.Note the last setting shown is DevicePhoneNumber and that it is not read only.
  • The below image shows the result of getting the settings. Notice that the DevicePhoneNumber is not set.
  • Press the Update Settings button to update the DevicePhoneNumber. Then press Get Settings to verify that it was set.
  • The DevicePhoneNumber value could also be retrieved and modified with the settings plugin using the below commands.
    <button onclick="sap.Settings.getConfigProperty(function(value) {alert(value)}, errorCallback, 'DevicePhoneNumber')">Get Device Phone Number</button>
    <button onclick="sap.Settings.setConfigProperty({'DevicePhoneNumber' : '123 456 7890'}, function(value) {alert(value)}, errorCallback)">Set Device Phone Number</button>

Settings Exchange using the Settings Plugin

The Settings plugin will perform a settings exchange with the SMP or HCPms server when an app starts. Changes then made in the management cockpit can then be effected on the registered apps. Specifically the log level and the automatic log upload behavior can be set in the management cockpit.

For additional details see C:\SAP\MobileSDK3\KapselSDK\docs\api\sap.Settings.html or Using the Settings Plugin.

  • This example builds on the sample index.html from the Logger section.
  • In the folder C:\Kapsel_Projects\KapselGSDemo add the settings plugin.
    cordova plugin add kapsel-plugin-settings --searchpath %KAPSEL_HOME%/plugins
    or 
    cordova plugin add kapsel-plugin-settings --searchpath $KAPSEL_HOME/plugins
    
  • Modify the init method of index.html and add in the following line.
    setTimeout(function() { getLogLevel(); }, 3000);

    This will update the Log Level select to the current log level received from the settings exchange.

  • Prepare, build and deploy the app with the following command.
    cordova run android
    or 
    cordova run windows -- --archs=x64 
    or
    cordova run ios
    
  • After adding the settings plugin, an exchange will occur each time that the application opens (not on a resume). During the settings exchange the log level specified for the application instance or registration and the log upload setting as set in the Management Cockpit is sent to the device. The settings plugin then acts on those values and sets the log level and performs a log upload.
    Note, if you wish to enable logs to be uploaded from the device when sap.Logger.upload() is called but do not wish the log to be uploaded each time a settings exchange occurs, comment out the sap.Logger.upload() call in settings.js. Similarly if you do not wish the log level of the app to be set in the management cockpit, comment out the sap.Logger.setLogLevel call in settings.js.
  • Prepare, build and deploy the project.
    cordova run android
    or 
    cordova run windows -- --archs=x64 
    or
    cordova run ios
    

    Notice that the debug level is ERROR by default.

    Use the Management Cockpit to change the log level to WARNING and enable the automatic uploading of the log for a particular registration by clicking on the Client Log icon for a registration.
    Note, you may need to change From and To filters to find the registration.

    Note, the mapping between the SMP or HCPms server log levels and the Kapsel log levels is mapped in the method setLogLevel in the following file.

    www/plugins/kapsel-plugin-logger/www/logger.js
  • Hit the back button on Android to close the application.On iOS press the home button to send the app to the background. Press the home button twice quickly and then swipe up on the Logger Demo app to remove it from memory.
  • Open Logger Demo and notice that the Log Level after a few seconds is changed to WARN.
    A new log file should also appear under Logs and Traces.

    Note, if the log does not appear it may appear under a previously uploaded log.

Back to Getting Started With Kapsel

To report this post you need to login first.

Be the first to leave a comment

You must be Logged on to comment or reply to a post.

Leave a Reply