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.
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.
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.
Run the application
Right click the Customers project> Run As> Android Application.
Midhun VP
@midhunvptwit
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:
When I Pressed the button, following exception occurred.

When I again tried to get the results, it gave me the following message
Please help me in this. I am new to android development.
Thanks
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
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
Debug the code and check in which line of code error occurs. It can be an android specific error too.
- Midhun VP
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 🙂
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
Sreeja,
You can attend this free course from SAP, that explains how to develop an app using SMP on cloud.
Midhun VP
can run on Android version 4.1.2? version is supported?
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
Hi,
have no idea of the following error?
Could you download the project and check where you are missing.
Hello,
This error is generated at the time of the download information from my native android app.
have no idea that it can be?
Hi Midhun,
I is not generating the following error, I know why this happening?
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
Hi Midhum,
SUP version I have is currently version 2.2 ...
should replace the libraries that I have now?
Yes, you have to replace the libraries. Copy and paste the libraries from SUP SDK to android project.