Technical Articles
Appendix E: Non Kapsel Plugins
The following examples demonstrate how to include and use some of the native functionality that Cordova plugins provide.
Taking, Storing and Retrieving a Picture
Acquiring the Device Location and Displaying it on a Map
Taking, Storing and Retrieving a Picture
The following steps demonstrate how to take a picture using the Cordova camera plugin and how to store and retrieve previously taken images.
- Create a new project named CameraDemo and add Android or iOS or both.
cordova create C:\Kapsel_Projects\CameraDemo com.mycompany.camera CameraDemo cd CameraDemo cordova platform add android cordova create ~/Documents/Kapsel_Projects/CameraDemo com.mycompany.camera CameraDemo cd ~/Documents/Kapsel_Projects/CameraDemo cordova platform add ios
- Add the Kapsel Encrypted Storage plugin, the Cordova Camera and Dialogs plugins.
cordova plugin add cordova-plugin-camera cordova plugin add cordova-plugin-dialogs cordova plugin add kapsel-plugin-encryptedstorage --searchpath %KAPSEL_HOME%/plugins or cordova plugin add kapsel-plugin-encryptedstorage --searchpath $KAPSEL_HOME/plugins
- Replace the contents of index.html with the below code.
<html> <head> <title>Camera Demo</title> <script type="text/javascript" charset="utf-8" src="cordova.js"></script> <script> var selectEl = null; var imageEl = null; var store = null; var firstTime = null; function onLoad() { selectEl = document.getElementById("imageNumSelect"); imageEl = document.getElementById("imageID"); } function addOption(select, text, value) { var option = document.createElement("option"); option.text = text; option.value = value; select.options.add(option); select.selectedIndex = select.options.length - 1; showImage(); } function populateSelectFromStore() { store.length(function(length) { for (var i = 0; i < length; i++) { store.key(i, function(key) { addOption(selectEl, key, key); }, onFail); } }, onFail); } function deletePhoto() { var selectedValue = selectEl.options[selectEl.selectedIndex].value; store.removeItem(selectedValue, successCallback, onFail); selectEl.options.remove(selectEl.selectedIndex); showImage(); } function showImage() { if (selectEl.options.length == 0) { imageEl.src = "data:image/jpeg;base64,"; return; } var selectedValue = selectEl.options[selectEl.selectedIndex].value; store.getItem(selectedValue, function(imageData) { imageEl.src = "data:image/jpeg;base64," + imageData; }, onFail); } function capturePhoto() { firstTime = true; navigator.camera.getPicture(onSuccess, onFail, { quality: 85, allowEdit: true, targetWidth : 399, targetHeight : 300, sourceType: navigator.camera.PictureSourceType.CAMERA, destinationType: navigator.camera.DestinationType.DATA_URL }); } function onSuccess(imageData) { if (firstTime) { //method is called twice on iOS. Not sure why. firstTime = false; imageEl.src = "data:image/jpeg;base64," + imageData; var imageName = prompt("Please enter a name for the image",""); //prompt doesn't work on Windows. Need to use navigator.notification.prompt and handle async. //store image store.setItem(imageName, imageData, successCallback, onFail); //update dropdown addOption(selectEl, imageName, imageName); } } function onFail(message) { firstTime = false; navigator.notification.alert("Failed because: " + message); } function init() { var appId = "com.mycompany.camera"; // Change this to app id on server var context = { "passcode": "password", //Note hardcoding passwords and unlock passcodes are strictly for ease of use during development //Once set can be changed by calling sap.Logon.managePasscode() "unlockPasscode": "password", "passcode_CONFIRM":"password", }; var passcodePolicy = { "expirationDays":"0", "hasDigits":"false", "hasLowerCaseLetters":"false", "hasSpecialLetters":"false", "hasUpperCaseLetters":"fales", "defaultAllowed":"true", "lockTimeout":"300", //5 minutes, if this is set too low (0), the data vault could be locked when coming back from the camera app and storing the picture will fail. "minLength":"6", "minUniqueChars":"0", "retryLimit":"0" }; //Used if the application is not registering with the SMP 3.0 server. New to SP03. sap.Logon.initPasscodeManager(logonSuccessCallback, errorCallback, appId, null, passcodePolicy, context); } function logonSuccessCallback() { store = new sap.EncryptedStorage("testStore"); populateSelectFromStore(); } function successCallback() { } function errorCallback(error) { navigator.notification.alert("An error occurred: " + JSON.stringify(error)); } document.addEventListener("deviceready", init, false); </script> </head> <body onload="onLoad()"> <button onclick="capturePhoto();">Capture Photo</button><br> <button onclick="deletePhoto();">Delete Photo</button><br> <select id="imageNumSelect" onchange="showImage()";> </select><br> <img src="" id="imageID"> </body> </html>
- Prepare, build and deploy the app with the following commands.
cordova run android or cordova run ios
Acquiring the Device Location and Displaying it on a Map
The following steps demonstrate how to get a location and then use Google services to translate a location into an address and to display a map showing the address.
- Create a new project named LocationDemo and add Android or iOS or both.
cordova create C:\Kapsel_Projects\LocationDemo com.mycompany.location LocationDemo cd LocationDemo cordova platform add android cordova create ~/Documents/Kapsel_Projects/LocationDemo com.mycompany.location LocationDemo cd ~/Documents/Kapsel_Projects/LocationDemo cordova platform add ios
- Add the InAppBrowser plugin to the project to enable showing the Google Map in a separate window that will have a close button. Also add the Dialogs and geolocation plugins.
cordova plugin add cordova-plugin-inappbrowser cordova plugin add cordova-plugin-dialogs cordova plugin add cordova-plugin-geolocation
- Replace the contents of index.html with the code below.
<html> <head> <title>Location Demo</title> <script type="text/javascript" charset="utf-8" src="cordova.js"></script> <script> function getLocation() { navigator.geolocation.getCurrentPosition(locSuccess, locFail, {maximumAge:10000, timeout:30000, enableHighAccuracy: true}); } function getAddress() { var lat = document.getElementById("latitude").value; var long = document.getElementById("longitude").value; var url = "https://maps.googleapis.com/maps/api/geocode/json?latlng=" + lat + "," + long + "&sensor=false"; //var url = "https://maps.googleapis.com/maps/api/geocode/json?latlng= &sensor=false" var xmlhttp = new XMLHttpRequest(); xmlhttp.open("GET", url, false); try { xmlhttp.send(); } catch (e) { navigator.notification.alert(JSON.stringify(e)); return; } var responseText = xmlhttp.responseText; var responseObj = JSON.parse(responseText); var address = responseObj.results[0].formatted_address; document.getElementById("address").value = address; } function locSuccess(position) { var latitude = position.coords.latitude; var longitude = position.coords.longitude; document.getElementById("latitude").value = latitude; document.getElementById("longitude").value = longitude; } function locFail(error) { console.log(JSON.stringify(error)); navigator.geolocation.getCurrentPosition(locSuccess, locFail2, {maximumAge:10000, timeout:30000, enableHighAccuracy: false}); } function locFail2(error) { console.log(JSON.stringify(error)); console.log("Failed to establish the device's location"); } function showStaticMap() { var lat = document.getElementById("latitude").value; var long = document.getElementById("longitude").value; var img_url="https://maps.googleapis.com/maps/api/staticmap?center="; img_url = img_url + lat + "," + long + "&zoom=14&size=400x300&sensor=false"; document.getElementById("mapholder").innerHTML="<img src='"+img_url+"'>"; } function showFullMap() { var lat = document.getElementById("latitude").value; var long = document.getElementById("longitude").value; var URLToOpen = encodeURI("https://maps.google.com/?q=" + lat + "," + long); //may be needed if URL contains parameters var ref = window.open(URLToOpen, '_blank ', 'location=yes'); //location bar shown or not //use _system if you wish to open in the system browser. } </script> </head> <body><br><br> <button onclick="getLocation();">Get Location</button><br> <button onclick="getAddress();">Get Address from Location</button><br> Latitude:<input type="text" id="latitude"><br> Longitude:<input type="text" id="longitude"><br> Address:<textarea rows="2" cols="30" id="address"></textarea><br> <button onclick="showStaticMap()">Show Static Map</button> <button onclick="showFullMap()">Show Full Map</button> <div id="mapholder"></div> </body> </html>
- Prepare, build and deploy the app with the following commands.
cordova run android or cordova run ios
If you are using Windows Phone, enable the location capability as shown below.
If using an Android emulator, the emulator’s location can be changed from the emulator’s extended controls under location.
On an iOS simulator the location can be changed under Debug > Location.
- Depending on the device, the location may not be returned before the timeout occurs.
On Android, ensure that the Location is enabled under Settings > Location > On. The Mode can also be set. Finally under recent location requests should appear LocationDemo if you have previously pressed the Get Location button.
On iOS, ensure that Location is enabled under Settings > Privacy > Location > Location Service > On
Hello Daniel,
I tried to build the application using cordova camera plugin. The camera plugin is not responding when we are accessing through the SAP fiori client in android mobile device.
Can you please suggest.
Thanks,
Gurung
What version of Android is the device running on?
What version of the Kapsel SDK are you using?
Does the app have permission to access the camera? This permission should be asked for the first time the app attempts to use the camera.
I believe you could also give this setting on the device by going to settings > Apps > your_app > Permissions.
I would recommend getting the latest patch for the 14 release of the Kapsel SDK if you haven't already.
Regards,
Dan van Leeuwen
Hello Daniel,
Thank you so much for prompt reply.
Android version : 6.0.1
The application is based out of HANA XS engine and configured in SAP HANA Launchpad.
SAP Fiori client access the SAP HANA Launchpad URL to access the application.
Yes the SAP fiori client has permission to access the camera.
cordova version : 6.1.2
Thanking you.
Thanks,
Gurung
I would recommend doing a cordova plugins and checking the version of the camera plugin.
I did find mention of an issue. Could this be related? Perhaps you could change the version of the camera plugin being used in your project.
The latest Cordova camera plugin (2.3.1) cannot be built with the Kapsel Logger plugin.
Element provider#android.support.v4.content.FileProvider at AndroidManifest.xml:40:9-42:20 duplicated with element declared at AndroidManifest.xml:12:9-14:20
/Users/i827005/androidtest/platforms/android/AndroidManifest.xml Error:
With 2.3.0 of the camera plugin I can build successfully.
Regards,
Dan van Leeuwen