Skip to Content
Author's profile photo Midhun VP

Developing SAP Android Mobile app from scratch – Part 4

Part 1 Part 2 Part 3 Part 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.

/wp-content/uploads/2014/02/35_385127.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.

/wp-content/uploads/2014/02/36_385242.jpg/wp-content/uploads/2014/02/37_385243.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.

/wp-content/uploads/2014/02/38_385247.jpg

Run the application

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

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



Download the project


Midhun VP

@midhunvptwit

Assigned Tags

      16 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Former Member
      Former Member

      Hi Midhun,

      Thanks for the nice post. I tried to do a small POC by following your blog.

      Few Issues I am facing when I tried to run the project on the android simulator.

      Please help me out.

      I have created a RFC which will take the input for username and will output the corresponding Issue_ID.

      I created a Personalization key called PK_USERNAME and hard-coded its value to the username for which I want to fetch the Issue ID.

      When I tried to run the project on the android simulator..

      Got the first screen as:

      /wp-content/uploads/2014/02/snapshot_1_396114.jpg

      When I Pressed the button, following exception occurred.
      /wp-content/uploads/2014/02/snapshot_2_396115.jpg

      When I again tried to get the results, it gave me the following message/wp-content/uploads/2014/02/snapshot_3_396127.jpgPlease help me in this. I am new to android development.

      Thanks

      Author's profile photo Midhun VP
      Midhun VP
      Blog Post Author

      Can you give the code you written. Have you added the SUP/SMP related libraries in your project? Test the app in android version 4.0. Download the project I attached with the blog and double the code written and the libraries.

      - Midhun VP

      Author's profile photo Former Member
      Former Member

      Midhun,

      I have added the SUP related libraries to my android work space that got generated in my SUP Generated Code. No error exists in the project.

      Here I am providing the code for SettingsActivity.java

      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("TestApp");// 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(), "ERROR1 OCCURRED-->" + e,

        Toast.LENGTH_SHORT).show();

        } catch (ExceptionInInitializerError e) {

        Toast.makeText(getBaseContext(), "ERROR2 OCCURRED-->" + 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,

        IssueList.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();

        System.out.println(connProps);

        connProps.setFarmId("0");

        connProps.setServerName("xxx.xx.xxx.xx");// 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

        TestAppDB.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 (!TestAppDB.databaseExists()) {

        TestAppDB.createDatabase();

        } else {

        TestAppDB.openConnection();

        }

        // Retrieve the synchronization profile object using the SAP

        // Mobile Platform database's getSynchronizationionProfile

        // method.

        ConnectionProfile connectionProfile = TestAppDB

        .getSynchronizationProfile();

        connectionProfile.setServerName("xxx.xx.xxx.xxx");// 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)

        // Assing Values to PK

        PersonalizationParameters param = TestAppDB

        .getPersonalizationParameters();

        param.setPK_USERNAME("Debidutta");

        param.save();

        TestAppDB.subscribe();

        // Make a blocking synchronize call to Unwired Server to

        // pull in all MBO data

        TestAppDB.synchronize();

        } catch (Exception e) {

        System.err.println("Exception Occurred");

        returnMsg = e.getMessage();

        }

        }

        return returnMsg;

        }

        }

      }

      Please check it and let me know your suggestions.

      Thanks

      Author's profile photo Midhun VP
      Midhun VP
      Blog Post Author

      Debug the code and check in which line of code error occurs. It can be an android specific error too.

      - Midhun VP

      Author's profile photo Former Member
      Former Member

      Hello...this is a very good tutorial,can you please make a similar one with SMP 3.0??

      I really have some issues to understand how the whole things work together in the new version.

      Thanks in advance and looking forward to see good tutorials from you 🙂

      Author's profile photo Sreeja Sreekumar
      Sreeja Sreekumar

      Hi Midhun

      This is a good one. Thank you for sharing the same  ..  would you be having any information on how to create and  link an apps to HANA in Cloud platform ?

      Thanks & Regards

      Sreeja

      Author's profile photo Midhun VP
      Midhun VP
      Blog Post Author

      Sreeja,

      You can attend this free course from SAP, that explains how to develop an app using SMP on cloud.

      Midhun VP

      Author's profile photo Former Member
      Former Member

      can run on Android version 4.1.2? version is supported?

      Author's profile photo Midhun VP
      Midhun VP
      Blog Post Author

      Android 4.1 is supported from version SUP 2.2. You can find more information here, http://infocenter.sybase.com/help/index.jsp?topic=/com.sybase.infocenter.dc01699.0222/doc/html/lly1336581622404.html

      Midhun VP

      Author's profile photo Former Member
      Former Member

      Hi,

      have no idea of the following error?

      /wp-content/uploads/2014/06/error_471120.png

      Author's profile photo Midhun VP
      Midhun VP
      Blog Post Author

      Could you download the project and check where you are missing.

      Author's profile photo Former Member
      Former Member

      Hello,

      /wp-content/uploads/2014/06/error2_471123.png

      This error is generated at the time of the download information from my native android app.

      have no idea that it can be?

      Author's profile photo Former Member
      Former Member

      Hi Midhun,


      I is not generating the following error, I know why this happening?


      Error3.png

      Author's profile photo Midhun VP
      Midhun VP
      Blog Post Author

      The sample project given is based on SUP 2.1.3, If you are in a different version replace the SUP libraries with respective libraries. Also check the points I mentioned here, Error Development SAP Android Mobile app

      Midhun VP

      Author's profile photo Former Member
      Former Member

      Hi Midhum,

      SUP version I have is currently version 2.2 ...

      should replace the libraries that I have now?

      Author's profile photo Midhun VP
      Midhun VP
      Blog Post Author

      Yes, you have to replace the libraries. Copy and paste the libraries from SUP SDK to android project.