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: 
Dan_vL
Product and Topic Expert
Product and Topic Expert
0 Kudos
1,174




Settings


The settings plugin is used to exchange settings between the SMP 3.0 server and a Kapsel application.  The following two samples will be used to demonstrate a settings exchange with the SMP server using REST APIs 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 the SMP 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 a file named register4.html in a folder on your laptop such as C:\temp.
<!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 userName = "i82XXXX";
var password = "XXXXXXX";
var host = "localhost"; //note if this value changes, also change Content Security Policy (the meta tag on line 4)
var baseAppIDStr = "/odata/applications/latest/com.mycompany.logon/";

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>


Modify the userName and password variables as appropriate. Modify the host and meta tag with the Content-Security-Policy if your host is not localhost.
Open the file in Chrome.
Press Register to register with the SMP 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.

Settings Exchange using the Settings Plugin


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

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

The following steps will demonstrate this plugin.

  • Change directory to LoggerDemo
    cd C:\Kapsel_Projects\LoggerDemo
    cd ~/Documents/Kapsel_Projects/LoggerDemo


  • Add the settings plugin to the LoggerDemo app.
    cordova plugin add kapsel-plugin-settings --searchpath %KAPSEL_HOME%/plugins
    or
    cordova plugin add kapsel-plugin-settings --searchpath $KAPSEL_HOME/plugins


  • Copy the files to the platform directory by running
    cordova prepare


  • 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 C:\Kapsel_Projects\LoggerDemo\plugins\kapsel-plugin-settings\www\settings.js and then call cordova prepare.  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.

  • Modify
    LoggerDemo/plugins/kapsel-plugin-settings/www/settings.js

    and add the line
    getLogLevel();  //updates the Log Level select to the value returned to the Kapsel app from the SMP 3.0 server

    to the end of the success callback of sap.Settings.start (around line 78).  This will update the Log Level select to the current log level received during the settings exchange.

  • Prepare, build and deploy the project.
    cordova run android
    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, the mapping between the SMP 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.

  • In the Management Cockpit it is possible to click on the log file and have it be downloaded to your computer.


Back to Getting Started With Kapsel

3 Comments