1 2 3 11 Previous Next

SAP Mobile Platform Developer Center

165 Posts

OBJECTIVE:

 

This Document explains steps how we can Deploy SAP Appbuilder Application for HWC based application .

 

REQUIREMENT:

 

Tools used in developing the application are:

Appbulider 1.0.1251

Simulator/device: any

 

We can deploy an Appbuilder application on Sybase control center 2.2 as Hybrid app, we need to follow following steps

1. After deploy application,navigate your kapsel development workspace there find folder name would be same as project name and expend www folder and make some changes into index.html file.

onDeviceReady = function() {

  // Launch application

  //init(false);

jQuery.sap.require("Application");

var oApp = new Application({ root : "myBody" });

  }

 

2.Suppose if you are using any web service for example oData service etc. then make change in a config.xml file:

                              orgin=https://hostname subdomains="true" />\

3.After that,you use PackagingTool for creating Hybrid application and it will generate one .jar file,The file we have to deploy into Sybase control center.

 

Packing Tool:


Go to C:\Sybase\UnwiredPlatform\MobileSDK22\HybridApp\PackagingTool, click on packagingtool.bat    

   

for 32-bit JDK, use packagingtool.bat

for 64-bit JDK, use packagingtool64.bat

4.Select any desired location to place the package of this app

1.PNG

 

 

5. Once you click on OK, it will open Hybrid App Packaging Tool

2.PNG

 

6. Click on New

    • Mention project name (Test)
    • Web Application Folder:folder path for application
    • Mention MBO Package Name: Test
    • MBO Package version: 1.0

3.PNG

 

7. Once you click Generate, a window will pop up (confirmation message)

4.PNG

 

8. Open SCC (SAP Control Center).

    • Click on Hyrbid Apps
    • Select Deploy option
    • Browse the file, (if it is valid file, you will see one message says..)

5.PNG

 

9. Assign this Hyrbid Apps to the registered user.

6.PNG

10. Test With Device

 

Your comments/suggestions are most welcome.


Thanks,

Shambhu Nath

Hello Precision Marketing evaluation users,

 

in this tutorial i'm going to share with you a Java sample code that will help you build your calls to the Precision Marketing partner API.

 

I assume you have a Partner API Developer-Id and secret, if you don't then please get yours or generate it as indicated in the previous tutorial: SPM Evaluation: First steps using the Partner API

 

 

 

The Java code below will:

    - (1) Create Segments from a csv template (POST)

    - (2) Get a Segment by code  (GET)

    - (3) Detete that Segment by ID (DELETE)

 

 

These 3 calls cover the POST, GET and DELETE  calls to the REST API which cover most cases.

 

Notes/troubleshooting:

 

 

Code (also attached):

 

 

package eclipsePackage;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.MalformedURLException;
import java.net.Proxy;
import java.net.ProxySelector;
import java.net.SocketAddress;
import java.net.URI;
import java.net.URL;
import java.util.Arrays;
import java.util.List;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.stream.JsonReader;
class Test {
    URL url = null;
    String urlStr = null;
    String paramStr = null;
    String signString = null; // Needless
    String strCmdUrl = null;
    String WEB_SERVER = "https://sprpartnerapisstaging.hana.ondemand.com";
    String URL_BASE = "/partnerapi/v1/rest";
    String DEVELOPER_ID="replace_with_your_developer_id";
    String SECRET = "replace_with_your_secret";
    String boundary =  "*****";
    String attachmentName = "csv";
    String attachmentFileName = "createSegments.csv";
    String crlf = "\r\n";
    String twoHyphens = "--";
    public static void main(String args[]) throws Exception {
//    Use this piece of code if you  are behind a proxy server. Update the proxy details accordingly
//      ProxySelector.setDefault(new ProxySelector() {
//
//            @Override
//            public List<Proxy> select(URI uri) {
//                return Arrays.asList(new Proxy(Proxy.Type.HTTP, new InetSocketAddress("proxy.wdf.sap.corp", 8080)));
//            }
//
//            @Override
//            public void connectFailed(URI arg0, SocketAddress arg1, IOException arg2) {
//                throw new RuntimeException("Proxy connect failed", arg2);
//
//            }
//
//
//
//        });
      Test test = new Test();
      test.execute();
    }
    private  String createTransactionId() throws IOException{
        HttpURLConnection connection = null;
        JsonParser parser = null;
        JsonReader reader = null;
        JsonElement jElement = null;
        JsonObject jObj = null;
        System.out.println("-- Get Transaction ID");
        strCmdUrl = "/transactionid/";
        String urlbaseStr = WEB_SERVER + URL_BASE;
        urlStr = urlbaseStr + strCmdUrl + DEVELOPER_ID;
        System.out.println("URLStr : " + urlStr);
        url = new URL(urlStr);
        String transactionId = null;
        connection = (HttpURLConnection) url.openConnection();
        connection.setUseCaches(false);
        connection.setDoOutput(false);
        connection.setRequestMethod("GET");
        connection.setRequestProperty("Content-type", "application/x-www-form-urlencoded");
        connection.setRequestProperty("Accept", "*/*");
        //Json
        parser = new JsonParser();
        reader = new JsonReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
        jElement = parser.parse(reader);
        jObj = jElement.getAsJsonObject();
        transactionId = jObj.get("data").getAsJsonObject().get("transactionId").getAsString();
        System.out.println("Response : " + jElement.toString());
        System.out.println("-- New transactionId-- : " + transactionId);
        reader.close();
    //    System.out.println("-- Header field (0) -- : " + connection.getHeaderField(0));
        //  connection.
        connection.disconnect();
    return transactionId;
    }
    private void execute() throws IOException{
        String urlbaseStr = WEB_SERVER + URL_BASE;
        String transactionId= null;
        HttpURLConnection connection = null;
        JsonParser parser = null;
        JsonReader reader = null;
        JsonElement jElement = null;
        JsonObject jObj = null;
        // (1)POST call: create a segment
        System.out.println("-- (1) -- Create Segments");
        transactionId = createTransactionId();
        strCmdUrl = "/segments?";
        paramStr = "_transactionid="+ transactionId;
        urlStr = urlbaseStr + strCmdUrl + paramStr;
        System.out.println("URLStr : " + urlStr);
        url = new URL(urlStr);
        connection = (HttpURLConnection) url.openConnection();
        connection.setUseCaches(false);
        connection.setDoOutput(true);
        connection.setRequestMethod("POST");
        connection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + this.boundary);
        connection.setRequestProperty("Accept", "*/*");
        connection.setRequestProperty("developer-id", DEVELOPER_ID);
        connection.setRequestProperty("developer-secret", SECRET);
        DataOutputStream request = new DataOutputStream(connection.getOutputStream());
        request.writeBytes(this.twoHyphens + this.boundary + this.crlf);
        request.writeBytes("Content-Disposition: form-data; name=\"" + this.attachmentName + "\";filename=\"" + this.attachmentFileName + "\"" + this.crlf);
        request.writeBytes(this.crlf);
        request.write(fileToByteArray());
        request.writeBytes(this.crlf);
        request.writeBytes(this.twoHyphens + this.boundary + this.twoHyphens + this.crlf);
        request.flush();
        request.close();
        //Json
        parser = new JsonParser();
        reader = new JsonReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
        jElement = parser.parse(reader);
        jObj = jElement.getAsJsonObject();
        // Print return
        System.out.println("Response : " + jElement.toString());
        reader.close();
        connection.disconnect();
    // (2)GET call: get the segment
        System.out.println("-- (2) -- Get Segment by Code");
        transactionId = createTransactionId();
        strCmdUrl = "/segments?";
        paramStr = "_transactionid="+ transactionId +"&segmentcode=DemoSegmentCode_2807737227";
        urlStr = urlbaseStr + strCmdUrl + paramStr;
        System.out.println("URLStr : " + urlStr);
        url = new URL(urlStr);
        String segmentid = null;
        connection = (HttpURLConnection) url.openConnection();
        connection.setUseCaches(false);
        connection.setDoOutput(false);
        connection.setRequestMethod("GET");
        connection.setRequestProperty("Content-type", "application/x-www-form-urlencoded");
        connection.setRequestProperty("Accept", "*/*");
        connection.setRequestProperty("developer-id", DEVELOPER_ID);
        connection.setRequestProperty("developer-secret", SECRET);
        //Json
        parser = new JsonParser();
        reader = new JsonReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
        jElement = parser.parse(reader);
        jObj = jElement.getAsJsonObject();
        System.out.println("Response : " + jElement.toString());
        segmentid = jObj.get("data").getAsJsonObject().get("segmentId").getAsString();
        System.out.println("-- SegmentID returned - "+segmentid);
        reader.close();
        //  connection.
        connection.disconnect();
        //(3) DELETE : delete the segment
        System.out.println("-- (3) -- Delete the segment by ID");
        transactionId = createTransactionId();
        strCmdUrl = "/segments?";
        paramStr = "_transactionid="+ transactionId+"&id="+segmentid;
        urlStr = urlbaseStr + strCmdUrl + paramStr;
        System.out.println("URLStr : " + urlStr);
        url = new URL(urlStr);
        connection = (HttpURLConnection) url.openConnection();
        connection.setUseCaches(false);
        connection.setDoOutput(false);
        connection.setRequestMethod("DELETE");
        connection.setRequestProperty("Content-type", "application/x-www-form-urlencoded");
        connection.setRequestProperty("Accept", "*/*");
        connection.setRequestProperty("developer-id", DEVELOPER_ID);
        connection.setRequestProperty("developer-secret", SECRET);
        //Json
        parser = new JsonParser();
        reader = new JsonReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
        jElement = parser.parse(reader);
        jObj = jElement.getAsJsonObject();
        // Print return
        System.out.println("Response : " + jElement.toString());
        reader.close();
        connection.disconnect();
    }
    private byte[] fileToByteArray(){
    FileInputStream fileInputStream=null;
        File file = new File("/Users/user1/Downloads/createSegments.csv");
        byte[] bFile = new byte[(int) file.length()];
        try {
            //convert file into array of bytes
    fileInputStream = new FileInputStream(file);
    fileInputStream.read(bFile);
    fileInputStream.close();
    return bFile;
    }catch(Exception e){
    e.printStackTrace();
    return null;
    }
}
}












 

How to get this code to work?

 

  1. Create you Java Package and copy/paste the java code (also attached)
  2. replace your developer_ID and secret
  3. copy the attached csv file to your local and update the path in the code.
  4. Reference the GSON library in your eclipse
  5. Check that there are no errors and run the code as Java application

 

You should get the below response:

-- (1) -- Create Segments
-- Get Transaction ID
URLStr : https://sprpartnerapisstaging.hana.ondemand.com/partnerapi/v1/rest/transactionid/<developer_id>
Response : {"meta":{"returnCode":"OK"},"data":{"transactionId":"3e886360-991e-4de3-baec-20bd54fcd278"}}
-- New transactionId-- : 3e886360-991e-4de3-baec-20bd54fcd278
URLStr : https://sprpartnerapisstaging.hana.ondemand.com/partnerapi/v1/rest/segments?_transactionid=3e886360-991e-4de3-baec-20bd54fcd278
Response : {"meta":{"returnCode":"OK"}}
-- (2) -- Get Segment by Code
-- Get Transaction ID
URLStr : https://sprpartnerapisstaging.hana.ondemand.com/partnerapi/v1/rest/transactionid/<developer_id>
Response : {"meta":{"returnCode":"OK"},"data":{"transactionId":"c7ce705a-87f8-47a7-bae9-ebb36c7b2657"}}
-- New transactionId-- : c7ce705a-87f8-47a7-bae9-ebb36c7b2657
URLStr : https://sprpartnerapisstaging.hana.ondemand.com/partnerapi/v1/rest/segments?_transactionid=c7ce705a-87f8-47a7-bae9-ebb36c7b2657&segmentcode=DemoSegmentCode_2807737227
Response : {"meta":{"returnCode":"OK"},"data":{"segmentId":2657,"segmentCode":"DemoSegmentCode_2807737227","segmentType":"DemoSegmentType","segmentName":"DemoSegmentName","segmentDescription":"DemoSegment","customerProfileIds":[],"offerIds":[]}}
-- SegmentID returned - 2657
-- (3) -- Delete the segment by ID
-- Get Transaction ID
URLStr : https://sprpartnerapisstaging.hana.ondemand.com/partnerapi/v1/rest/transactionid/<developer_id>
Response : {"meta":{"returnCode":"OK"},"data":{"transactionId":"82df6c7f-624d-4d8a-bc81-bb7d23e5537b"}}
-- New transactionId-- : 82df6c7f-624d-4d8a-bc81-bb7d23e5537b
URLStr : https://sprpartnerapisstaging.hana.ondemand.com/partnerapi/v1/rest/segments?_transactionid=82df6c7f-624d-4d8a-bc81-bb7d23e5537b&id=2657
Response : {"meta":{"returnCode":"OK"}}








 

 

 

Congrats, you just built your first calls to the Partner API in Java!

 

What now?

 

You should now be able to make all the other calls described in the SPM Partner API documentation, they are all built using the same pattern.

The full documentation of the partner API is available here: https://help.sap.com/spm  select the Partner Services API Documentation


have fun modeling your tenant, and send us feedback via the comments below or by writing to SAPprecisionmarketing-info@sap.com

Louay

In this post, I will try to guide your first steps using the Partner API of SAP Precision Marketing.

This is targeted to SPM evaluation users and I assume you have already gone through this: Getting started with the SPM evaluation

 

 

The Partner API is the programatic interface to manage your retailer instance, you can create stores and offers and all other artefacts via this API.

The Partner Portal Interface allows you to use a friendly interface for many actions (create stores, create campaigns and offers) however you should consider using Partner API if you need to integrate with other systems, or if you have too many stores or offers that becomes unmanageable manually via the interface.

 

The API is a RESTFUL interface and as per SPM v2.5 there are no SDKs (unlike the Device API).

 

For this tutorial I recommend you use the Partner API with the developer-ID/secret authentication method, that is simpler for the developer as it requires less steps to make the call, you may consider later using the developer-ID/certificate authentication method depending on your security requirements (see the product documentation for more).

 

The full documentation of the partner API is available here: https://help.sap.com/spm  select the Partner Services API Documentation

 

 

Now let's get started,

 

Create a developer-Id and a secret

 

If you already have a Developer ID and secret then you may skip this section.

Note that the Device API and the Partner API have different developer_ids, if you are unsure keep reading.


Log in the Partner Portal using the retailer Admin

go to the API credential tab.

click create Partner API Key and select the developer secret option.

enter a secret password/phrase and save, the system will generate a partner API key for you to use in conjunction with the secret.


Keep the developer-ID and secret safely, you will use them for all your subsequent calls to the Partner API



Get the Google Chrome REST Advanced client


In this tutorial we will use the Google REST Advanced client to make the REST calls, it will be up to you to then make these calls from whatever development languages that Support REST.

install the REST Advanced client from the Chrome Web Store



Generate a TransactionID


All calls to the Partner API must include a TransactionID, this transactionID is valid for only 1 call and expires after a few minutes.

therefore you will need to generate a new key each time.

To Generate a transactionID you need to make a GET call to https://sprpartnerapisstaging.hana.ondemand.com/partnerapi/v1/rest/transactionid/<developerid>


Start the Chrome REST Advanced client fill the fields as shown here

 

Screen Shot 2014-04-03 at 3.28.48 PM.png

press the send button you will get the transactionID as part of the response:


Screen Shot 2014-04-03 at 3.32.23 PM.png

Make your first request


Now we're going to request Company information using the TransactionID that we got.

Let's use the GET company call


the url looks like this (using the transactionID that you generated in the previous section)

https://sprpartnerapisstaging.hana.ondemand.com/partnerapi/v1/rest/company/?_transactionid=928292b4-0b2c-4861-88ce-b5309…


and you will need to add your developerID and secret in the header of the call as shown below:

Screen Shot 2014-04-03 at 3.56.24 PM.png

Hit the send button and you will see some information about your tenant in the response.


Screen Shot 2014-04-03 at 5.37.56 PM.png


if you do, then congrats, you just succeeded with your first call !!

The other calls are constructed in a similar way, let's proceed.



Create your first stores


I'll now guide you to create your first stores via the API.

the main advantage over the User Interface is to create the stores in a batch call from a csv file.

I attached a sample csv file to this page for reference, avoid using Excel to edit it as it inserts unwanted metadata, prefer something neutral such as notepad or equivalent.


Check the documentation for a full description of all the fields at https://help.sap.com/spm  select the Partner Services API Documentation (Section: Create stores)



Generate a new transactionID as shown previously and use it in the URL

enter the  your developerID and secret in the header of the call

attach the csv file as Payload 

choose multipart/form-data

Method: POST


your screen would look like this.


Screen Shot 2014-04-03 at 4.11.05 PM.png

press the send button, you should get an OK back.



Get all stores


Now let's check that the stores were actually created successful let's make a GET stores call now.


We will use the same URL for stores (with a new transactionID), and select the GET method.

put the credentials in the header as before.


it should look like:


Screen Shot 2014-04-03 at 4.28.06 PM.png


hit the send button and you should get the response as shown below:

Screen Shot 2014-04-03 at 4.51.29 PM.png



Want to do more?


Well, you now have the basics... the other calls are constructed in the same way, you will fine a list of all the REST calls in the Partner API doc available here: https://help.sap.com/spm  select the Partner Services API Documentation



Give it a try and share your feedback.

enjoy!




Things you need:

 

1. Eclipse, either Juno or Kepler

2. Cordova - Search in SCN for my blog on how to use Cordova, SAPUI5 Development with Android & iOS using Cordova             

3. SAPUI5 SDK

4. You need Base64.js which is needed for Basic authentication

 

It's assumed that you have the necessary setup for development.  It is also assumed that you have setup an application ID setup on the SMP 2.3 bounded to an end point.

 

First create a new SAPUI5 Project.  You will need the Sever Host and Application Id for the OData end point from your SMP 2.3 Admin.

 

For example: Host Name: http://myserver.com:8080.  The format of the URL that you will eventually will be referring to is: http://<SUPServermachine>:8000/odata/applications/v1/<ApplicatinID>/Connections    

 

Add the following method in your view controller.js:

 

//Register the device that requires the use of an application id end point

        createConnectionId: function(usrName,pwd,appId,baseurl) {

           

               //Where baseurl = http://<SUPServermachine>:8000/odata/applications/v1/

               //where appId = <ApplicationID>

               //The user name and password can be passed on to SMP to get authenticated against LDAP or ActiveDirectory

            try {

                this.userName = usrName;

                this.pwd = pwd;

                this.appId = appId;

                this.baseurl = baseurl;

                this.method = "POST";

                //register application

                   var accessInfo = usrName + ":" + pwd;

                   var url = baseurl + "/" + appId + "/Connections";

               

                var xmlhttp = new XMLHttpRequest();

                xmlhttp.open(this.method,url,false);

                xmlhttp.setRequestHeader("Authorization", "Basic " + Base64.encode(accessInfo) );

                xmlhttp.setRequestHeader("Accept", "application/xml,application/atom+xml");

                xmlhttp.setRequestHeader("Content-Type", "application/atom+xml");

                //xmlhttp.setRequestHeader("X-SUP-SC","<SecConfigName>");

                //var t = generateEnvelope();

                /****************** envelope *******************/

                var postData = "<?xml version='1.0' encoding='UTF-8'?>" +

                                "<entry xmlns='http://www.w3.org/2005/Atom' xmlns:m='http://schemas.microsoft.com/ado/2007/08/dataservices/metadata' xmlns:d='http://schemas.microsoft.com/ado/2007/08/dataservices'>" +

                                "<content type='application/xml'>" +

                                "<m:properties>" +

                                "<d:DeviceType>iPad</d:DeviceType>" +

                                "</m:properties>" +

                                "</content>" +

                                "</entry>";

                /****************** envelope *******************/

                xmlhttp.send( postData );

                if( xmlhttp.readyState === 4) {

                    var tmpStr = "";

                    var foundNode = "false";

                    var xmlResponse = xmlhttp.responseXML;

                   

                    //parsing application connection id manually

                    for(var i=0; i<xmlResponse.length; i++) {

                       // responseXML contains many node elements.  But the one you are interested in is this node: "ApplicationConnectionId"

                    }

                }//if readystate

            }//try

            catch(error) {

                alert("Connection Id Error: " + error.message);

            }//catch

           

        }

 

Once you are able to save the connectionID value, you are ready to connect to your datasource

 

in the controller.js file, add this method:

 

          //create the XMLHttpRequest connection with the proper header settings including parameters

        createEndPointRequestHeader: function(connectionid, method,username, password,odataquery) {

              

               //where connectionid is where you got from your first connection

               //where method are: PUT, GET, DELETE, POST

               //username and password - pretty obvious

               //where odataquery is your OData query format, for example:

                             

          var url = "http://<baseURL>/<appliationID>/ServiceEndPoint?$filter=FirstName eq 'John";

 

            try {

               //the connectionid is added in the request header

                var xmlResponse;

                var accessInfo = username + ":" + password;

                this.xmlhttprequest = new XMLHttpRequest();

                this.xmlhttprequest.open(method,odataquery,false);

                this.xmlhttprequest.setRequestHeader("Authorization", "Basic " + Base64.encode(accessInfo) );

                this.xmlhttprequest.setRequestHeader("Accept", "application/xml,application/atom+xml");

                this.xmlhttprequest.setRequestHeader("Content-Type", "application/atom+xml");

                this.xmlhttprequest.setRequestHeader("User-Agent", navigator.userAgent);

                //Request Header specific to OData Query

                this.xmlhttprequest.setRequestHeader("X-SMP-APPCID", connectionid);

                this.xmlhttprequest.setRequestHeader("X-CSRF-TOKEN", "GET");

                this.xmlhttprequest.send();

                //process response body

                if( this.xmlhttprequest.readyState === 4) {

                    xmlResponse = this.xmlhttprequest.responseText;

                    //alert(xmlResponse);

                }

                return xmlResponse;

            }//try

            catch(error) {

                alert("Create end point request header error: " + error.message);

            }//catch

        }

 

You do need to delete your current connection id or reuse it.  But you have to manage this yourself.  To delete your current connection id on say, application exit, add this method in your controller.js:

 

//Delete a registered application connection

        deleteConnectionId: function(baseurl, connectionid, usrName, pwd) {

 

               //By this time, the parameters should start to make sense to you

            try {

                //alert("asfasdfd");

                var accessInfo = usrName + ":" + pwd;

                this.userName = usrName;

                this.pwd = pwd;

                this.baseurl = baseurl;

                this.connectionid = connectionid;

                var accessInfo = usrName + ":" + pwd;

                   var url = baseurl + "/Connections('" + connectionid + "')";

                   //alert(url);

                   this.xmlhttprequest = new XMLHttpRequest();

                   this.xmlhttprequest.open("DELETE",url,false);

                this.xmlhttprequest.setRequestHeader("Authorization", "Basic " + Base64.encode(accessInfo) );

                this.xmlhttprequest.setRequestHeader("Accept", "application/xml,application/atom+xml");

                this.xmlhttprequest.setRequestHeader("Content-Type", "application/atom+xml");

                this.xmlhttprequest.setRequestHeader("User-Agent", navigator.userAgent);

                //Request Header specific to OData Query

                this.xmlhttprequest.setRequestHeader("X-SMP-APPCID", connectionid);

                this.xmlhttprequest.send();

                //alert(this.xmlhttprequest.readyState);

                if( this.xmlhttprequest.readyState === 4) {

                    xmlResponse = this.xmlhttprequest.responseText;

                    //alert("Connection Deleted Successfully");

                }

               

            }//try

            catch(error) {

                alert("Delete Connection Error: " + error.message);

            }//catch

        }

 

 

Hopefully this is useful in one way or the other.  Thanks.

Thought I'd share these basic steps to get people started with SAPUI5 and Cordova for mobile development.  Like all my blogs, these are basic crash course meant for a quick start.  Hope this helps someone out to get started quickly and concentrating more on coding rather than trying to figure out how to setup.  We've gotten two apps out on pilot as soon as we got the procedures below.  Happy coding!

  1. Download Eclipse Kepler or Juno install
  2. Download Cordova 3.3.0
  3. Download Apache Ant - this is more relevant for Android
  4. SAPUI5 UI Development Toolkit
  5. Android ADT SDK
  6. Latest version install of the Java SDK or Java JRE.  This should have been installed on desktop.  To determine if this is installed, open a Windows Command Prompt and type the command: java -version.  It should show:

 

java version "1.7.0_45"

Java(TM) SE Runtime Environment (build 1.7.0_45-b18)

Java HotSpot(TM) 64-Bit Server VM (build 24.45-b08, mixed mode)

 

Note: With the exception of the Android ADT SDK, the rest are ZIP compressed file where you need to un-compress them in a location where it is easy for you to get to.  It is advised to extract them at the 'C' drive

 

  1. Extract Eclipse
  2. Extract Cordova
  3. Extract Apache Ant
  4. Extract SAPUI5
  5. Extract Android ADT SDK


Location would look like this:

 

 

Where:

  • Android - adt-bundle-window-86
  • Cordova - cordova-3.3.0-src
  • Apache Ant - apache-ant-1.9.3
  • Eclipse - Eclipse

Adt bundle and Apache Ant must be setup in the Windows Environment

 

To setup the environment:

  1. Click on the windows start button
  2. Right click on "Computer"
  3. On menu items, click on "Properties"
  4. In the "System" Window, select "Advanced System Settings"
  5. In "System Properties", select "Environment Variables"
  6. In the "Environment Variables" & "System Variables", select "Path"
  7. At the end of the "Variable value" field, the following paths:  C:\adt-bundle-windows-x86\sdk\tools, C:\adt-bundle-windows-x86\sdk\platform-tools, C:\apache-ant-1.9.3\bin

 

Run "android" from the ADT "tools" sub-folder to install the SDK

 

Note that for iOS, Xcode, all these must be setup in MacOS.  Except for Eclipse.  The cordova ClI creates an Xcode project file

 

Setup Android

 

  1. Open Windows Command line
  1. Change directory to phonegap2.2.0\bin sub-folder
  1. Type the command: create <project_path> <package> <project_name>.  For example: create c:\projects\cordovaAndroid com.saskpower cordovaAndroid
  2. Change directory to C:\cordova-2.2.0\framework to build and update project target

 

android update project -p <c:\temp\androidproject> -t android-19

 

 

  1. File > New > Project...
  2. Android > Android Project
  3. Create project from existing source (point to the generated app found in tmp/android)
  4. To create your cordova.jar, copy the commons codec:

mv commons-codec-1.6.jar framework/libs

then run in the framework directory:

 

   

 

android update project -p . -t android-19

  

 

ant jar

 

  1. Right click on libs/cordova.jar and add to build path
  2. Right click on the project root: Run as > Run Configurations
  3. Click on the Target tab and select Manual (this way you can choose the emulator or device to build to)

 

 

 

Project in Eclipse should look like this:

 

 

You make all your code changes in the "www" sub-folder.  Note the "cordovaAndroid-CordovaLib" project. This is in conjunction with the initial cordovaAndroid project.  Make sure that both this projects are open in Eclipse in order to have proper compile. The "apk" file is located in the "bin" folder

 

For iOS

 

The "create" command is in "cordova-ios".  When the "create" command runs sucessfully, you can open the generated Xcode project in Xcode and the folder structure is very similar to that of Android and Eclipse.  This "create" command does need to be on MacOS with Xcode installed. There's no way around this.

 

- open terminal

- change directory to cordova-ios/bin

- run this command: ./create <path of project> <package> <project name>

     Example: ./create /User/username/Documents/MyCordovaProject com.mycordovaproject MyCordovaProject

 

Hybrid App using SAPUI5 Framework

 

  1. Extract the UI_Development_Toolkit for SAPUI5
  2. You will find the "sapui5-mobile-static.zip" file, extract this as well
  3. Copy the "resources" folder and paste into the same folder where your index.html, css, js are located

          4. Paste the code snippet below into your index.html

 

<!DOCTYPE html>

<html>

<head>

<meta charset="ISO-8859-1">

<title>Outage Finder</title>

 

<!--  Load SAPUI5 mobile -->

<script src="resources/sap-ui-core.js" id="sap-ui-bootstrap" data-sap-ui-libs="sap.m" data-sap-ui-theme="sap_bluecrystal"></script>

 

<!-- App specific functions -->

<script src="js/outage.js"></script>

<script src="js/Base64.js"></script>

<script>

 

      // create a mobile App

      // it initializes the HTML page for mobile use and provides animated page handling

      var app = new sap.m.App("myApp", {initialPage:"Outage Finder"}); // page1 should be displayed first

     

     

      // create the first page of your application

      var outagemap = new sap.m.Page("outagemap", {

          title: "24 Hours Outages",

          /*content : new sap.m.Button({   // content is just one Button

              text : "Go to Page 2",

              press: function() {

app.to("page2");   // when pressed, it triggers drilldown to page 2

              }

          })*/

          initApp();

      });

     

     

      // create the second page of your application

      var page2 = new sap.m.Page("page2", {

          title: "Page 2",

          showNavButton: true,       // page 2 should display a back button

          navButtonPress: function(){

              app.back();            // when pressed, the back button should navigate back up to page 1

          },

          icon: "http://www.sap.com/global/ui/images/global/sap-logo.png",

          content : new sap.m.Text({text:"Hello Mobile World!"})

      });

     

app.addPage(page1).addPage(page2); // add both pages to the App

     

app.placeAt("content"); // place the App into the HTML document

      

    </script>

    <!-- App specific functions -->

 

</head>

<body class="sapUiBody" role="application">

<div id="content">

<!--  div id="outagemap" style="margin: 0 auto; width: 100%; height: 100%; border:1px solid blue;"></div -->

</div>

 

</body>

</html>

Dear All,

 

Objective: This blog gives an understanding about how can an SMP HWC based app can be authenticated with SAP username and password.

 

Tools Required: SUP 2.2.x, SMP 2.3.x

 

Procedure:

 

SCC Configuration:


  1. Open SAP Control Center (Sybase Control Center), Create a new security profile
    • Security>New>Give some name

       

               secHWCAuth.PNG

 

2.   Expand Security tab in the left hand side and select new created security profile name "HWCAuth"

    • Go to Authentication tab. Click "New"
    • Select Authentication provider as HTTPAuthenticationLoginModule
    • Make Control flag as Required
    • Add the URL of SAP system (You can check this blog to know how to check URL: How to check SAP system URL?)
    • SSO cookie name: MYSAPSSO2

 

               secSettings.PNG


    • Press OK
    • Delete NoSecLoginModule from the list
    • Similarly delete NoSecAuthorizer from Authorization tab and NoSecAttributer from Attribution tab
    • General tab > Apply


3.   If you want to create a new domain, you can do so. Domains>New>Give some name

    • Add newly created Sec configuration to this domain
    • Finish it

 

          Domain.PNG


4. Registering a user in SCC:


  • Make sure you select the settings as mentioned in the screen:

   

          SCCRegistration.PNG



MBO Modeling and Deploying to SMP server:


 

  1. Assuming you have successfully made SAP and SUP connection profiles in the mobile workspace.
  2. While creating an MBO ,select Runtime Data Source Credential and Connection properties
  3. From the drop down, select username and password (as shown in the diagram)

 

Some points for Runtime Data Source Credential and Connection properties :

 

  • Here user name and password will act as runtime inputs to the MBO.
  • Does not support MBO's that belong to a cache group that uses a Scheduled cache policy.

                         RuntimeCredentials.PNG

 

  4.  Deploy MBO to newly created domain and sec configuration.

 

    

 

               DeployingDomain.PNG

 

 

 

 

Creating UI screen:

 

  1. Right click project> New>hybrid App designer> give some name
  2. Select Starting points as mentioned in below diagram

 

               HybridAppDesigner.PNG

 

 

3. This is how Flow Design look like. If you open Credential Request screen, you will find two inputs already been defined as username and password.

 

FlowDesign.PNG

 

4. For easy UI development, i have dragged and dropped MBO to create 2 more screens. BAPIMBO, BAPIMBODetail

 

 

          screens.PNG

 

 

5. Go to start screen, add a new input field and add a menu to retrieve the data from backend.

 

     UILogic.PNG

 

 

  6. Assign the workflow app to user from workspace.


          AssigningUser.PNG



Simulator settings and screen flow:


  1. Make sure you have provided all settings in HWC container and user has been registered successfully.

 

          HWCsettings.PNG



2. This is how the application home page looks like:


     screens.PNG



Note: If you enter wrong credentials and press "SAVE" and call mbo, it will not move to next screen and you will see credentials screen again and again until you pass correct id and password.


I hope this write-up will help you to understand how to use HTTPAuthenticationLoginModule in SMP HWC based apps.

Your comments/suggestions are most welcome.


Rgrds,

Jitendra

Hi All,

 

This blog gives a basic understanding of how we can make a successful connection to Oracle database in SAP Mobile Workspace along with step by step Oracle DB installation.

 

 

Part 1: Installing Oracle DB on a server machine

Part 2: Creating a connection profile in SMP Mobile Workspace

 

Tools:  Windows Server 2008 R2 Standard 64 bit, SMP 2.3, Oracle Database 11g R2. Oracle DB SQL Developer 4.0


Steps to install Oracle DB:


  1. Download required Oracle Database setup with proper version  from this link


          Oracle Database 11g Release 2 for Microsoft Windows (x64)

 

64BitInstallation.PNG

    • Accept License Agreement.(Make sure you are logged in with valid username and password, If you don't have already registered user details, then register it NOW)
    • You need to download both files Part 1 and Part 2

 

2.  Once download completes, exact both files and you will see that both extracted files contain folder with same name "database" . Copy "database" folder      from Part 2 extracted file to Part 1 extracted file

                              installationFolder.PNG

 

    • Double click on setup file as shown above.

          

                    2.PNG

3. At the Configure Security Updates screen, you may ignore providing email address, just uncheck the box.

 

 

                         1.PNG

     If you haven't given email address in above then you will prompted for a warning message, Again you can ignore it.

 

                              emailAddress.PNG

 

4. Select "Create and Configure a database" option

                             step2.PNG

5. Choose "Desktop Class"

 

                              systemClass.PNG

 

 

6.  This is important step.

    • You may choose any location. (Default is D:/app/administrator)
    • If you are changing Global Database Name, make sure you remember it all the time.
    • You will have to set administrator password as well.

Note: This password has certain standards like it should contains at least one lowercase letter, one uppercase letter, one digit and should be of at least of 8 characters in length. (But for simplicity i have used "sql")

    • Ignore the warning if you have not followed standards.

                              SID.PNG

 

    • You must be seeing this step, perform Prerequisite Checks

                            PrerequsitieCheck.PNG

 

           

    • Here you can check the progress status

                               progress.PNG

 

 

7. Before installation gets complete, you will see another window Database Configure Assistant, which will complete following tasks:

 

  • Copying database files
  • Creating and starting Oracle Instance
  • Completing Database Creation

                    databaseConfigureAssistant.PNG

8, Click on Password Management, Here you will see different user names with their status if it is locked or not.

 

    • By default, there are two users SYS and SYSTEM which are unlocked, you can set a password for them. (Make sure you follow password standards otherwise again warning message pops-up), Press OK.

 

                    passwordManagement.PNG

 

 

 

9. Finally, You will a message on the screen saying

 

Your database configuration files have been installed in D:\app\Administrator while other components selected for installation have been installed in D:\app\Administrator\product\11.2.0\dbhome_1.  Be cautious not to accidentally delete these configuration files


                         close.PNG


10.   To test if this installation is successful, run this link in a browser, make sure you provide the correct credentials, You can see Oracle Database Control sheet.


https://localhost:1158/em/


                              databasecontrol.PNG




Steps to install Oracle SQL Developer:



  1. Download the required installation from below link:

 

Oracle SQL Developer

 

           oracleSQLDeveloper.PNG                

 

 

2.  Extract the zip file and start the installation.

          sqldeveloperInstallationPath.PNG

 

3. If you wish to import some preferences from already installed SQL Developer Installation, then select YES otherwise NO.

               sqldevelopersteps.PNG

 

4. Once installation is complete, you will see a Start Page for Oracle SQL Developer like below:

               StartPage.PNG

 

 

5. Next task is create a test connection,

    • Click on New Connection
    • Provide existing username and password
    • Make sure you provide the correct SID
    • Click on Test, If details are correct, you will see a Success status.

 

          statusConnection.PNG

 

6. Once test connection is connected, we can many folders like Tables, Views, Indexes, Packages etc. We can test existing tables.

 

 

folders.PNG

 

(Here we can create our tables as per requirement, this blog is for testing purpose only.)

 

Part 2 : Creating a connection profile in SAP Mobile Workspace and a test MBO

Part 2: Creating a Oracle DB connection profile in SAP Mobile Workspace 2.3:

 

Part 1 gives a clear understanding of how we can install and setup a connection in Oracle DB.

 

Steps:

 

  1. Right Click Database Connection in Enterprise Explorer,

  

    • Select New> Oracle> Give some connection profile name
    • Specify required DB driver details
    • Select Oracle Thin Driver and move to Jar List option as showing in below screenshot
    • You must be seeing ojdbc14.jar file already available there, remove it
    • Click on Add JAR, look for jar file available in installed Oracle DB path (D:\app\Administrator\product\11.2.0\dbhome_1\owb\wf\lib)

 

 

                    workspace1.PNG

    • Provide required SID (Global Database name, it is same id what you would set in step 6 of Part 1.
    • Required user name and password
    • Test the connection

 

                    connection.PNG

 

 

2.   Once the connection is successful, you would see lots of Schemas available under newly created connection. Select any table available in any Schemas.

 

          EmpTable.PNG

 

Make sure you copy the same odjc14.jar file in below location:

 

C:\SAP\MobilePlatform\Servers\UnwiredServer\lib\3rdparty

C:\SAP\MobilePlatform\MobileSDK23\MobileWorkSpace\mobile\eclipse\plugins\com.sybase.uep.com.oracle_2.3.0.201301212158\lib

 

 

3. For easy understanding, i have selected EMPLOYEES table under  HR Schema. Drag and drop this to create an MBO.

 

                    empMBO.PNG

 

From this step onward, we can go with any MBO mobile application development connecting to Oracle DB.

 

 

Rgrds,

Jitendra

Inspired by Mocking up the Payroll Control Center Fiori App from DJ Adams I built a quick and dirty prototype using the AppBuilder. While you get all the details about AppBuilder in other blogs (this is a good starting page: SAP AppBuilder Developer Center) I just want to show you a simple use-case how you can consume external data and showcase them in the AppBuilder.

 

Use Case

Recently there were some discussions on Twitter where to ask questions regarding SAPUI5 and openUI5. While SCN still is the place to go, there are also some questions rised on StackOverflow recently. Therefore I make use of the public OData endpoint of StackOverflow which has the URL http://data.stackexchange.com/stackoverflow/atom.

 

For our simple demo app the goal is to select the newest Posts tagged with something like UI5 and show them in the app. Therefore we can use the query http://data.stackexchange.com/stackoverflow/atom/Posts?$filter=substringof(%27ui5%27,%20Tags)%20eq%20true&$orderby=LastA…

Here we are filtering all posts that have the substring of ui5 inside one of their tags.

 

Now that we have access to the data we can start to build the app.

 

 

Configuring an App in SMP Cloud

AppBuilder allows you to consume data from various sources, OData being one of them. You can connect to OData sources directly or via the SAP Mobile Platform, on premise or in the cloud.

Because the direct connection to the StackOverflow service did not work for me I opted for the second option to consume the service indirectly via the SMP Cloud.

 

There I created an application de.mte.stack :

SMP3 App.png

The endpoint is simply the OData service from StackOverflow. Now I can consume the OData of this application via the AppBuilder in order to build my demo app.

 

Building the Prototype in AppBuilder

First I have to create an application profile in the AppBuilder:

AppBuilder SMP App Profile.png

Only the URL to the SMP (I used my free trial account here) and the Application ID of the app are needed here. The next step is to connect to the SMP Cloud and retrieve the details of the provided service.

SMP3 Server Profile.png

Here an  application connection to the SMP Cloud is created automatically. After a successfully created connection you can see the details of the provided service. As shown above the service offers collections of Badges, Comments, Posts etc. As we like to see the Posts regarding UI5 we create in another step a SMP OData Query that is based on the Posts collection:

SMP3 New SMP ODATA Source.pngSMP3 New SMP ODATA Source 2.png

AppBuilder allows us also to get a preview of the data here:

preview.png

Now I used this data to build a Superlist with a List view and Detail view and implemented the Superlist in my demo app. Details for the steps needed can be seen here: AppBuilder Tutorial - SuperList

Result

The created prototype now can be started inside AppBuilder or it can be exported as an Eclipse project or even deployed as a Kapsel app on SMP.

In the AppBuilder itself it looks like this:

App.png

Conclusion

With AppBuilder you can create a prototype including real data very fast. But there are some downsides to be aware of. While the tool supports drag and drop and offers a WYSIWYG perspective you can use only a small palette of UI controls. Elements like the SuperList are not standard UI5 controls and the documentation is not very detailed at the moment.

 

Also things like Navigation bar are already included but you have to code some cryptic stuff in order to make it really usable. In my example the navigation from List to Detail works out of the box via the Superlist but you cannot navigate back from Detail to List view. And when I show the Navigation bar I can see the back button but it does not work. Also it is visible on the List page, too.

 

In the next couple of months it is planned to integrate the AppBuilder into some Eclipse Web Application Tools. So maybe it does not make much sense to use AppBuilder at this early stage because many things will change soon. But at least for some small examples it may be a handy tool.

 

What do you think about AppBuilder? Would it be useful for you? Or do you prefer text editors like Sublime, Vi or Notepad for building your prototypes?

Part 1Part 2Part 3Part 4

Few lines of code

The screens of the android mobile application were designed in XML. Given below is the XML used in the start screen of the application that contains a TextView and a Button. The Textview carries a welcome text. The button click will trigger the connection with the Unwired Server and synchronizes.

35.jpg

Given below is the code used in the SettingsActivity Class, where it registers the user and sync the data to device.

package com.example.customers;

import android.app.Activity;

import android.app.AlertDialog;

import android.app.ProgressDialog;

import android.content.DialogInterface;

import android.content.Intent;

import android.os.AsyncTask;

import android.os.Bundle;

import android.util.Log;

import android.view.Menu;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.Button;

import android.widget.Toast;

import com.sybase.mobile.ConnectionProperties;

import com.sybase.mobile.RegistrationStatus;

import com.sybase.persistence.ConnectionProfile;

import com.sybase.persistence.LoginCredentials;

import com.sybase.sap.BAPI_CUSTOMER_GETLIST_IDRANGE;

import com.sybase.sap.CustomersDB;

import com.sybase.sap.PersonalizationParameters;

 

public class SettingsActivity extends Activity {

             com.sybase.mobile.Application app;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

//Set the activity content to an explicit view.

setContentView(R.layout.activity_settings);                 

//Initializing button created in the layout

Button button = (Button)findViewById(R.id.button1);              

//when the button is pressed what should happen is written inside this method.

             button.setOnClickListener(new OnClickListener() {                                 

@Override

public void onClick(View v) {

try{

// Initializing Sybase mobile application

app = com.sybase.mobile.Application.getInstance();

if (app.getApplicationIdentifier() == null){

              app.setApplicationIdentifier("Customers");//Name of the MBO project

            app.setApplicationContext(SettingsActivity.this);

}

// An Async class is called once app is initialized

new getRegister().execute();

}catch (Exception e) {

          Toast.makeText(getBaseContext(),"ERROR-->"+e, Toast.LENGTH_SHORT).show();

}catch (ExceptionInInitializerError e) {

          Toast.makeText(getBaseContext(),"ERROR-->"+e, Toast.LENGTH_SHORT).show();

}

}

});

}

public class getRegister extends AsyncTask<Void, Void, String> {

ProgressDialog dialog = new ProgressDialog(getBaseContext());

@Override

protected void onPostExecute(String result) {

          super.onPostExecute(result);

          dialog.dismiss();

          AlertDialog.Builder builder = new AlertDialog.Builder(

          SettingsActivity.this);

if (result.equalsIgnoreCase("success")) {

Intent go = new Intent(SettingsActivity.this, CustomerList.class);

startActivity(go);

} else {

          builder.setTitle("ERROR !")

.setMessage(result)

.setPositiveButton("OK",

new DialogInterface.OnClickListener() {

@Override

public void onClick(DialogInterface dialog, int which) {

}

}).create().show();

}

}

@Override

protected void onPreExecute() {

          super.onPreExecute();

dialog = ProgressDialog.show(SettingsActivity.this, "Connecting",

"\"Device with Unwired Server\"", true);

}

@Override

protected String doInBackground(Void... params) {

String returnMsg = "success";

try {

// Setting connection properties

// ConnectionProperties has the information needed to register and connect SUP server

ConnectionProperties connProps = app.getConnectionProperties();

          connProps.setFarmId("0");

          connProps.setServerName("10.10.10.10");// IP of SUP server

// if you are using Relay Server, then use the correct port number for the Relay Server.

// if connecting using http without a relay server, use the messaging administration port, by default 5001.

// if connecting using https without a relay server, then use a new port for https, for example 9001.

          connProps.setPortNumber(5001);

// Initialize generated package database class with this Application instance

          CustomersDB.setApplication(app);

// Provide user credentials

LoginCredentials loginCredentials = new LoginCredentials(

                             "supAdmin", "s3pAdmin");

          connProps.setLoginCredentials(loginCredentials);

// Initialize generated package database class with this Application instance

if (app.getRegistrationStatus() != RegistrationStatus.REGISTERED) {

// If the application has not been registered to the SUP server, register now

          app.registerApplication(600);

} else {

// start the connection to SUP server

          app.startConnection(600);

}

} catch (Exception e) {

returnMsg = e.getMessage();

}

if (returnMsg == "success"){

try {

//Connect to the generated database by calling the generated database instance's openConnection method.

if (!CustomersDB.databaseExists()) {

            CustomersDB.createDatabase();

} else {

            CustomersDB.openConnection();

}

// Retrieve the synchronization profile object using the SAP Mobile Platform database's getSynchronizationionProfile method.

ConnectionProfile connectionProfile = CustomersDB

.getSynchronizationProfile();

            connectionProfile.setServerName("10.10.10.10");//SUP server IP

            connectionProfile.setPortNumber(2480);

            connectionProfile.setNetworkProtocol("http");

            connectionProfile.setAsyncReplay(true);

            connectionProfile.setDomainName("default");

            connectionProfile.save();

//The input of the RFC is a table, hence the data-type of the Personalization Key(PK) is also table

//So the input to PK is passed as range that contains multiple set of data (here we have only one set)

BAPI_CUSTOMER_GETLIST_IDRANGE range  = new BAPI_CUSTOMER_GETLIST_IDRANGE();

            range.setSIGN("I");

               range.setOPTION("BT");

          range.setLOW("0");

          range.setHIGH("9");

          com.sybase.collections.GenericList<BAPI_CUSTOMER_GETLIST_IDRANGE> rangeList = new                     com.sybase.collections.GenericList<BAPI_CUSTOMER_GETLIST_IDRANGE>() ;

          rangeList.add( range ) ;

//Assing Values to PK

PersonalizationParameters param = CustomersDB.getPersonalizationParameters();

          param.setPK_CustomerInput(rangeList);

          param.save();

          CustomersDB.subscribe();

//Make a blocking synchronize call to Unwired Server to pull in all MBO data

          CustomersDB.synchronize();

}catch (Exception e) {

returnMsg = e.getMessage();

}

}

return returnMsg;

}

}

}

Create a simple ListActivity class to show the list of customers fetched from SAP server. To create a new class right click on the package com.example.customers> New> Class.

36.jpg37.jpg

Add following lines of code inside the new class. It calls a simple listview in the screen.

package com.example.customers;

import java.util.ArrayList;

import java.util.List;

import android.app.ListActivity;

import android.os.Bundle;

import android.widget.ArrayAdapter;

import android.widget.ListAdapter;

import com.sybase.sap.Customers;

 

public class CustomerList extends ListActivity {

@Override

protected void onCreate(Bundle savedInstanceState) {

     super.onCreate(savedInstanceState);

ListAdapter adapter = createAdapter();

setListAdapter(adapter);

}

protected ListAdapter createAdapter()

{

List poset = new ArrayList();

//Finall is the query generated by SUP to get the data from the table Customers.

//Customers is the MBO name in SUP and table name in Device DB

for(Customers itemheader : Customers.findAll())

{

     poset.add(itemheader.getNAME());

}

ListAdapter adapter = new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_list_item_1, poset);

return adapter;

}

}

In the Android project add the permissions to access INTERNET, READ_PHONE_STATE, ACCESS_WIFI_STATE, ACCESS_NETWORK_STATE, WRITE_EXTERNAL_STORAGE by openining AndroidMenifest.xml file. Also add the newly created ListActivity (CustomerList) in it.

38.jpg

Run the application

Right click the Customers project> Run As> Android Application.

droid@screen-1.pngdroid@screen-2.png



Download the project


 

Regards,

Midhun VP; LinkedIn, Twitter

Part 1Part 2Part 3

Part 4

Create Android Project and Import Libraries

The client object APIs form the core building block of Native Object API Applications and provide the common set of APIs for consistency across device platforms, thus following the "design once and deploy anywhere" paradigm of building applications.

 

Client Object API categories for Native Object API Application development include:

  • Object APIs that supports access to MBOs attributes, operation execution, retrieving data, state information, and so forth. The APIs offer abstraction for accessing data from the EIS, sending operation executions to the EIS, updating and deleting data, and accessing persistent store in the object-oriented paradigm, among other things.

 

  • Object APIs that offer consistent access to core application services across all device platforms. The APIs provide abstraction for the complex technical details of reliable communication between the device and Unwired Server. This includes a variety of network conditions for optimal transmission of data and state information, connection APIs to the back-end infrastructure, secure access to the Unwired Server data, publishing of data notifications and processing of such notifications, data protection, and access to UI management APIs and custom UI controls, such as signature control, among other things.

 

Install the Android SDK, and run the eclipse.exe to start the android app development. When running the eclipse for first time it asks to set up the workspace where the project will be saved.

19.png

Right click under project explorer> New> Android Application Project, and provide the below details.

21.jpg22.jpg23.jpg

Click Finish. It creates an activity class with name “SettingsActivity”.

25.jpg26.jpg

Add the compiler and Sybase libraries to the root directory of the Android project. Copy the following files from Sybase installed directory (SDK) and paste it to the libs folder in Android project.

27.png               30.jpg

Modify the build path to point to the correct location for the ClientLib.jar, sup-client.jar, and UltraLiteJNI12.jar files for the project. Right click on project Customers> Properties> Java Build path. Click on Libraries> Add JARs…

28.jpg29.jpg

31.jpg32.jpg

Copy the object API code generated to the Customers android project inside src folder. Copy the com folder inside the Customers MBO project> Generated code> src.

33.jpg                                     34.jpg

Next

 


Part 1Part 2Part 3Part 4

Create PK and Generate Code

A Personalization Key is needed to pass input from device to SAP. This key will be used while developing native app to pass the input from mobile device to SAP server. “IDRANGE” is the load parameter (ie. RFC input) of the MBO. Right click on the folder “Personalization Keys”> New> Personalization key.

c.jpg

Give the below details in the personalization key window, click on Finish button after setting the values. Storage can be kept server or client in the case of native application. If server is selected the Personalization key value will be stored in the server and client option stores the Personalization key value in the device itself.

9.png

Map the PK “PK_CustomerInput” with the Load Argument of MBO.

10.png

Right click on the project and click on Deploy Project that deploys the project to Unwired Server. From SCC (Sybase Control Center) navigate to packages under default domain to see the deployed MBO package.

13.png

Generate Object API

The Sybase Unwired Platform Android Client Object API consists of generated business object classes that represent the mobile business object model built and designed in the Unwired WorkSpace development environment. The Object API representing the MBO model of “Customers” project can be generated from SUP workspace.

The Android Client Object API is used by device applications to synchronize and retrieve data and invoke mobile business object operations.

Right click the Customers project and select Generate code.

14.png

On the code generation configuration screen, click Next.

15.png

Make sure the Customer and Customers_List MBOs are selected, and then click Next.

16.png

Specify the given below values and click Finish.

17.png

The code will be generated in the Project path mentioned (\Customers\Generated Code). The error in the generated code can be ignored. This generated code will be used in the android application during development.

18.png

 

Next

Part 1Part 2Part 3Part 4

Download the project


This blog helps the newbies to develop a native mobile app from scratch using Sybase Unwired Platform's MBO approach. This approach has been discouraged by SAP, eventhough the MBO based apps are supported in SMP 3 version using the SMP 2.3 runtime. I am not getting into detail on the future plans of SAP in this blog. Hope this blog can answer a lot of repeated basic questions on a native application development using SUP.

The mobile app was developed in this blog based on SUP 2.2 SP02 and Andriod mobile OS with SAP as backend.

To set up a development read this blog, Setup mobile development environment. Apart from this installation of Android SDK is needed.

 

Creating MBOs

In this part the MBOs are developed and deployed to SUP server. There is only one MBO called Customers_List in this project.

Create a new mobile application project by right clicking in a free space under WorkSpace Navigator > New> Mobile Application Project.

new project.jpg

Give a name for the project “Customers”.

1.png

It will create a new project in the Workspace.  Create an MBO called Customers_List  by right clicking on the folder Mobile Business Objects.

Give name for the MBO.

2.png

Specify a database from the choice bar. The Sybase SDK is configured with SAP connection details, hence it appears in the list. Select SAP and click Next.

SAP connection selection.jpg

Click on browse to fetch the RFCs/BAPIs. Give the name of the RFC (BAPI_CUSTOMER_GETLIST) and click on “Search BAPIs/RFCs” button that will get the list of RFCs. Select the RFC and click OK. The RFC used is present in SAP system by default.

3.png

Select “IDRANGE” as input and “ADDRESSDATA” as output. Click on next button.

4.png

Click next.

5.png

Click the Next button and click Finish. It will create the MBO.

6.png

7.png

8.png

Note that the MBO Customers_List is linked to BAPI_CUSTOMERGETLIST_IDRANGE structure, since the input of the RFC is a structure.

Next

 

 

 

 

SAP HANA has been sweeping businesses and consumers alike with Big Data promises and an interconnected future. HANA is SAP’s powerhouse Big Data solution, which records and analyzes massive amounts of smart data at a time. During the first phases of HANA’s debut, few companies understood it and even fewer had a legitimate need for it. But now in early 2014, SAP has come up with another solution that will once again change the way the world looks at Big Data: Cloud Connector.

 

 

 

 

 

 

While early variants of the Cloud Connector have been around for a while, now that HANA’s popularity is rising, the service is getting some major attention and newfound appreciation. With dozens (dozens!) of companies implementing a Big Data mobility strategy in Q1, many are looking for a workable solution that remains powerful but isn’t tied to on-premise hardware. On-premise costs are still higher than a service-based approach, so SAP’s Cloud Connector is just the right fit. Cloud Connector serves as a kind of bridge between on-premise hardware and on-demand applications hosted with SAP.

The potential applications of the technology are limitless. Having a hybrid solution (some on-premise, some cloud) is an excellent way for enterprise and small business to take part in growing mobility trends without relying too heavily on uncontrolled factors or paying large, up-front technology costs.

The following error codes occurs when you connect iOS device to Relay server

 

1) Error code 231 and Error code 86 occurs when you are not set the certificate path and url suffix to networkstram params

2) Error code 61 occurs when you have set only RBS Farm ID for SUP connection profile and SUP connection properties. To avoid this error use MBS FarmID      in SUPConnection Properties and RBS FarmID in SUPConnectionProfile

 

Sample code for connecting iOS device to relay server


//To set up a messaging client connection, use:
SUPApplication *app=[SUPApplication getInstance];
[app setApplicationIdentifier:APPLICATION_IDENTIER];
[app setApplicationCallback:self.callbackHandler];
[Demo_AppDemo_AppDB registerCallbackHandler:self.callbackHandler];

   

    //MBS for device registeration

SUPConnectionProperties* props = app.connectionProperties;
[props setServerName:server];
[props setPortNumber:CONTROL_PORTNUMBER]; //80 HTTP or 443 for HTTPS
[props setNetworkProtocol:CONTROL_PROTOCOL]; // or https for secure connection
[props setUrlSuffix:@"/ias_relay_server/client/rs_client.dll/MBSFARMID/"];
[props setFarmId:CONTROL_FARMID];

  

SUPLoginCredentials* login = [SUPLoginCredentials getInstance];
login.username = app_user; // same as in Application Connection
login.password = nil;
props.loginCredentials = login;
props.activationCode = activation;// same as in Application Connection
props.securityConfiguration =CONTROL_SECURITY_CONFIG;

   

    //RBS for Data synchronization

SUPConnectionProfile *sp = [ Demo_AppDemo_AppDB getSynchronizationProfile];
[sp setUser:scc_username];
[sp setPassword:scc_password];
[sp setAsyncReplay:NO];
[sp setServerName:server];
[sp setPortNumber:CONTROL_PORTNUMBER]; // or 80 for http
[sp setNetworkProtocol:CONTROL_PROTOCOL];

   

    //Import the CA certificate (which is used in Relay server) to your Xcode project

NSString *cer_path=[[NSBundle mainBundle]pathForResource:@"demoapp-certserv-rca" ofType:@"cer"];
NSString *cer_name=[NSString stringWithFormat:@"trusted_certificates=%@",cer_path];
NSString *params=[NSString stringWithFormat:@"%@;compression=zlib;url_suffix=/ias_relay_server/client/rs_client.dll/RBSFARMID/",cer_path];

   

    //set the certificate to network stream params

[sp setNetworkStreamParams:params];
[ Demo_AppDemo_AppDB setApplication:app];

   

    //Print the network stram params to ensure that certificate path is added

NSLog(@"NETWORK PARAM %@",[ Demo_AppDemo_AppDB getSynchronizationProfile].getNetworkStreamParams);

   

if(![ Demo_AppDemo_AppDB databaseExists]){
  
    [ Demo_AppDemo_AppDB createDatabase];
  
    NSLog(@"DB CREATION");
  
}

   

@try{
    if([SUPApplication registrationStatus]==SUPRegistrationStatus_REGISTERED)
    {
      
        [app startConnection:0];
        NSLog(@"Start app Connection");
    }
    else
    {
      
        [app registerApplication:0];
        NSLog(@"Register app Connection");
        return YES;
    }
}
@catch(SUPApplicationTimeoutException *pe){
    NSLog(@"%@ : %@",[pe name],[pe message]);
  
}

Actions

Filter Blog

By author:
By date:
By tag: