Android Client App for consuming SAP SOAP Web services using ksoap2 library

Recently SAP lauched their SAP Mobile Platform 3.0 (more about that here ) and I decide to write about how one can develop an Android Client App that can consume SAP SOAP Web Services with the ksoap2 library. I am maybe a bit late but it still deserves some attention.

Even though recently I had the chance to try out for myself the SAP Mobile Platform 2.2 and develop some Demo Apps testing both MBO and OData concepts I still personally feel that there are many people out there that are still developing mobile apps for SAP the old-fashion-way: ask for their SAP ABAP developers to prepare a couple of web services and develop mobile clients for these.

One point is that many companies still haven’t updated their Netweaver Gateways, so they can not use the OData goodies that come along with the newer versions. Another reason is that a change of mindset is needed and acceptance of the new web technologies and REST as an architecture.  And lest but not least is that there is still not a stable concept about the offline data management. MBOs were built with keeping that in mind, but SAP has decided not to support it anymore as it was a propriatery “protocol”. The Delta Query support that they mention sounds promising here but I have to try it out in order to judge it 🙂

I have one very old post about consuming SAP web services (or it should be consuming .NET web services that call RFC-enabled Function Modules from an SAP-Backend) where the landscape I had for development was SAP Backend, Visual Studio and SAP .NET connector library. Well, this time I had SAP Backend with enabled Webservices Runtime and as any normal developer would do: I made the use of the web services that you can build with SAP from any Remote-enabled Function module and develop clients that would consume this services. The best library out there that one can make use of at the moment is ksoap2 and since it is free you can use it and adapt it to your needs. I actually came to the idea of this blog post after reading many forums where people complained that they didn’t manage to get it work or they had to change the source and rebuild it after changing the names of the tags or something in the XML bulding logic.

How am I using the ksoap2 library to consume SAP Web services? Very elegant and smooth actually.

1. I developed an wrapper class for the SAPSerializationEnvelope that inherits from the SoapSerializationEnvelope where I just make it create XML-Requests in the SAP manner.

import java.io.IOException;
import org.ksoap2.SoapFault;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.xmlpull.v1.XmlSerializer;

public class SAPSerializationEnvelope extends SoapSerializationEnvelope {

public String namespace;
 public SAPSerializationEnvelope(int version, String namespace) {
 super(version);
 this.namespace= namespace;
 }

 @Override
 public void write(XmlSerializer writer) throws IOException {

writer.setPrefix("urn", namespace);
 writer.setPrefix("soapenv", env);
 writer.startTag(env, "Envelope");
 writer.startTag(env, "Header");
 writeHeader(writer);
 writer.endTag(env, "Header");
 writer.startTag(env, "Body");
 writeBody(writer);
 writer.endTag(env, "Body");
 writer.endTag(env, "Envelope");

 }

@Override
 public Object getResponse() throws SoapFault {
 return super.getResponse();
 }

}

2. Made a helper class for making calls.

import java.util.ArrayList;
import java.util.List;
import org.ksoap2.HeaderProperty;
import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;

public class SAPServiceCaller {

String NAMESPACE_SOAP = "http://schemas.xmlsoap.org/soap/envelope/";
 static String NAMESPACE = "urn:sap-com:document:sap:soap:functions:mc-style";
 static String SOAP_ACTION = "";

 public static SoapObject webServiceCall(SoapObject request, String URL, boolean imp_types){
 SoapObject response = null;

 SAPSerializationEnvelope envelope = new SAPSerializationEnvelope(
 SoapEnvelope.VER11, NAMESPACE);
 envelope.implicitTypes = imp_types;
 envelope.dotNet = false;
 envelope.setAddAdornments(false);
 envelope.env = SoapSerializationEnvelope.ENV;

 envelope.setOutputSoapObject(request);

 HttpTransportSE androidHttpTransport = new HttpTransportSE(URL, 30000);
 try {
 List<HeaderProperty> headerList = new ArrayList<HeaderProperty>();
 headerList.add(new HeaderProperty("Authorization", "Basic "
 + org.kobjects.base64.Base64.encode("USER:PASS"
 .getBytes())));
 headerList.add(new HeaderProperty("Connection", "Keep-Alive"));
 androidHttpTransport.debug = true;
 androidHttpTransport.call(SOAP_ACTION, envelope, headerList);
 String answer = androidHttpTransport.responseDump;
 response = (SoapObject) envelope.bodyIn;
 }catch(Exception e){
 e.printStackTrace();
 }

 return response;
 }

}

3. And used it later in calls. A simple call is as follows.

SoapObject request = new SoapObject(
 "urn:sap-com:document:sap:soap:functions:mc-style",
 "ZbapiGetRoutes");
 request.addProperty("RoutesList", "");
SoapObject response;
response = SAPServiceCaller.webServiceCall(request, URL, false);
 SoapObject routesList = (SoapObject) response.getProperty("RoutesList");

This is a simple code that calls a method to return a list of Routes that one has to visit and read the meters in homes and upload them later to the backend.
With this simple “trick” I managed to build a Demo app for an SAP Backend with ISU Component that was displaying the Routes and devices from which the Meter data were read and uploaded to the backend for later billing purposes.

Hope it helps someone out there.

In the following posts I will try to keep up with the trends and write something about what I learned from the course that SAP was offered at openSAP  about Mobile development with the SAP Mobile Platform and maybe other ways how to achieve this as well.

Happy coding!

Monkeyrunner can help you recover ColorNote password

This time I engaged myself in some “cracking” activity after a stressed conversation I had with a friend.
*** If you came to this Blogpost because you locked your phone and you are not really IT person please read the comment below from Ashley***
There is a not so quick but not so ‘hackerish’ workaround:
—-
actually i discover a method, that is once u restart u smart phone, u enter the colornote it aint required any password, then u faster screenshots the contents inside, it only persist for around 5 seconds, then will log out , so u keep restart then u cn get bck all the things inside dy simply by screenshots…. this is what i do to take bck my thngs as i frgt my lock pattern as well =)
—-
Thanks Ashley!

This is how it all happened…

I was chatting with a friend when suddenly(quite stressed) she asked me if I know someone ( i quote) “who can crack an Android application”?! Since  I don’t usually support cracking anything I wanted her to explain exactly what she meant with that sentence.  So, she had installed an application – ColorNote on her phone that allows locking files with certain important information with some so-called master password. Then the files are encrypted and there is no way of decrypting them if you don’t know the password. First I tried to calm her down telling her to search the web for some solution. I installed the application, tested it for a while, created some files of my own, locked some of them, did a backup…. All of that went smooth! I must say that the developers have done a really good job with this app. Even if someone gets my files they are still encrypted with the password I put! The problem arises when I forget the master password of the application! If you want to change it all of the files that were encrypted with it are DELETED?!!! After reading many forums/blogs/discussions it became clear to me that there is no solution to the problem other than deleting all the locked files which seemed like the developers missed to solve a quite trivial problem! What if I store my credit card pin in it and I am somewhere away from home and I urgently need it? What if I have stored my bank details and I need them immediately for some transaction? What if I have stored some other really important information? And even though I am sure at the time of creating the master password that I will remember it always, it might happen that I forget it, right? So this really got me angry and I decided to find a way how to prove that even their concept was not the perfect one…

So I came to an idea to write a simple monkeyrunner script that would generate combinations of letters/numbers that came to my mind that I might have put as a password. There is no limit in the number of tries to enter the password so..  I was right.. this really worked!

Here is the script that I used for “cracking” my ColorNote master password.

# Imports the monkeyrunner modules used by this program
from __future__ import generators
from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice

def xcombinations(items, n):
    if n==0: yield []
    else:
        for i in xrange(len(items)):
            for cc in xcombinations(items[:i]+items[i+1:],n-1):
                yield [items[i]]+cc

def xuniqueCombinations(items, n):
    if n==0: yield []
    else:
        for i in xrange(len(items)):
            for cc in xuniqueCombinations(items[i+1:],n-1):
                yield [items[i]]+cc

def xselections(items, n):
    if n==0: yield []
    else:
        for i in xrange(len(items)):
            for ss in xselections(items, n-1):
                yield [items[i]]+ss

def xpermutations(items):
    return xcombinations(items, len(items))

if __name__=="__main__":

# Connects to the current device, returning a MonkeyDevice object
    device = MonkeyRunner.waitForConnection()

# sets a variable with the package's internal name
    package = 'com.socialnmobile.dictapps.notepad.color.note'

# sets a variable with the name of an Activity in the package
    activity = 'com.socialnmobile.colornote.activity.NoteList'

    print device.getProperty('display.width'), device.getProperty('display.height')

# sets the name of the component to start
    runComponent = package + '/' + activity

# Runs the component
    device.startActivity(component=runComponent)

# Presses the Menu button
    device.press('KEYCODE_MENU','DOWN_AND_UP')

    MonkeyRunner.sleep(1)
    device.touch(240, 750, 'DOWN_AND_UP')
#device.drag((230, 750), (240, 760), 2.0, 2) 

    MonkeyRunner.sleep(1)
    device.touch(240, 350, 'DOWN_AND_UP')

    MonkeyRunner.sleep(1)
    device.touch(120, 500, 'DOWN_AND_UP')

#MonkeyRunner.sleep(1)
#device.type('5551234')

#MonkeyRunner.sleep(1)
#device.touch(240, 350, 'DOWN_AND_UP')

#MonkeyRunner.sleep(1)
#device.type('5551234')

    MonkeyRunner.sleep(1)
    #device.type('color')
    #device.touch(240, 350, 'DOWN_AND_UP')
#device.touch(240, 350, 'DOWN_AND_UP')

    #for num in range(2000, 2003):
    #    print num
    #    device.type(str(num))
    #    MonkeyRunner.sleep(1)
    #    device.touch(240, 350, 'DOWN_AND_UP')

    print "Permutations"
    for p in xselections(['3','4','6','5','2'],4):
        print ''.join(p)
        device.type(''.join(p))
        MonkeyRunner.sleep(1)
        device.touch(240, 350, 'DOWN_AND_UP')

Here is a video of the monkeyrunner working on my phone! I put simple password just to make the video short so that you can see the result of the script.

NOTE: In order to make it work on your phone you’d have to check the screen size and tune the clicks.

NOTE1: This script lasts up to couple of hours but if the right letters/numbers are put it might solve your problem! Also this is something that I’d suggest to people who really are in need of their encrypted data! (and till the developers don’t think of a solution!)

And a final NOTE to the developers: Think of a way in the next update (using IMEI, PIN, mail, other…) how to solve this problem and I’d put this app in my all time Android favs!

Accordion-like widget for Android

I had some Android project this last week and I came to a problem.  I wanted to make an accordion-like view for a part of the application that I am making and since I have a short deadline the first thing that came to my mind was to search what others have done. I only managed to find a simple idea given on the Android developer’s mailing list but I couldn’t find any code available.

So I decided to publish my code in order to help others that would like to implement accordion-like view for Android quick and simple or simply to learn more. I must say that for any other problem it would need a lot customization and this code that I’ll publish here is more like an implementation of a design pattern for making accordion widget.

Here is a video of how it looks like in the Emulator.

So first it is important to talk about the layout design. It was done following the suggestion given here.  I won’t explain much I think that it is very clear how it is done ;).

So I’ll simply paste part of my main.xml code here:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:id="@+id/root_layout" android:layout_width="fill_parent"
	android:layout_height="fill_parent" android:background="#FFFFFFFF"
	android:layout_weight="1" android:orientation="vertical">
	<Button android:id="@+id/btnProfile" android:layout_width="fill_parent"
		android:layout_height="wrap_content" android:text="Profile"
		android:textColor="#FFFFFFFF" />
	<LinearLayout android:id="@+id/panelProfile"
		android:orientation="vertical" android:layout_width="fill_parent"
		android:layout_height="wrap_content" android:layout_weight="1"
		android:background="#FFFFFFFF">
		<LinearLayout android:id="@+id/panelProfile1"
			android:orientation="horizontal" android:layout_width="fill_parent"
			android:layout_height="wrap_content" android:layout_weight="1"
			android:background="#FFFFFFFF">
			<TextView android:id="@+id/strName" android:layout_width="wrap_content"
				android:layout_height="wrap_content" android:text="Name" />
			<EditText android:id="@+id/txtName" android:layout_width="fill_parent"
				android:layout_height="wrap_content" />
		</LinearLayout>
		<LinearLayout android:id="@+id/panelProfile2"
			android:orientation="horizontal" android:layout_width="fill_parent"
			android:layout_height="wrap_content" android:layout_weight="1"
			android:background="#FFFFFFFF">
			<TextView android:id="@+id/strSurname" android:layout_width="wrap_content"
				android:layout_height="wrap_content" android:text="Surname" />
			<EditText android:id="@+id/txtSurname" android:layout_width="fill_parent"
				android:layout_height="wrap_content" />
		</LinearLayout>
	</LinearLayout>
	<Button android:id="@+id/btnSettings" android:layout_width="fill_parent"
		android:layout_height="wrap_content" android:text="Settings"
		android:textColor="#FFFFFFFF" />
	<LinearLayout android:id="@+id/panelSettings"
		android:orientation="vertical" android:layout_width="fill_parent"
		android:layout_height="wrap_content" android:layout_weight="1"
		android:background="#FFFFFFFF">
		<LinearLayout android:id="@+id/panelSettings1"
			android:orientation="horizontal" android:layout_width="fill_parent"
			android:layout_height="wrap_content" android:layout_weight="1"
			android:background="#FFFFFFFF">
			<TextView android:id="@+id/strMail" android:layout_width="wrap_content"
				android:layout_height="wrap_content" android:text="e-mail" />
			<EditText android:id="@+id/txtMail" android:layout_width="fill_parent"
				android:layout_height="wrap_content" />
		</LinearLayout>
		<LinearLayout android:id="@+id/panelSettings2"
			android:orientation="horizontal" android:layout_width="fill_parent"
			android:layout_height="wrap_content" android:layout_weight="1"
			android:background="#FFFFFFFF">
			<TextView android:id="@+id/strPhone" android:layout_width="wrap_content"
				android:layout_height="wrap_content" android:text="Phone" />
			<EditText android:id="@+id/txtPhone" android:layout_width="fill_parent"
				android:layout_height="wrap_content" />
		</LinearLayout>
	</LinearLayout>
	<Button android:id="@+id/btnPrivacy" android:layout_width="fill_parent"
		android:layout_height="wrap_content" android:text="Privacy"
		android:textColor="#FFFFFFFF" />
	<LinearLayout android:id="@+id/panelPrivacy"
		android:orientation="vertical" android:layout_width="fill_parent"
		android:layout_height="wrap_content" android:layout_weight="1"
		android:background="#FFFFFFFF">
		<CheckBox android:id="@+id/checkFacebook"
			android:layout_width="fill_parent" android:layout_height="wrap_content"
			android:layout_weight="1" android:text="Facebook" android:textColor="#ff355689">
		</CheckBox>
		<CheckBox android:id="@+id/checkLinkedIn"
			android:layout_width="fill_parent" android:layout_height="wrap_content"
			android:layout_weight="1" android:text="LinkedIn" android:textColor="#ff355689">
		</CheckBox>
		<CheckBox android:id="@+id/checkTwitter"
			android:layout_width="fill_parent" android:layout_height="wrap_content"
			android:layout_weight="1" android:text="Twitter" android:textColor="#ff355689">
		</CheckBox>
	</LinearLayout>
</LinearLayout>

Then it is very important to use the parameter

android:visibility="gone"

for all the clicks performed on different buttons.

Here is the code for the activity.

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class AccordionActivity extends Activity {
	/** Called when the activity is first created. */

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		Button btnProfile = (Button) findViewById(R.id.btnProfile);
		Button btnSettings = (Button) findViewById(R.id.btnSettings);
		Button btnPrivacy = (Button) findViewById(R.id.btnPrivacy);

		View panelProfile = findViewById(R.id.panelProfile);
		panelProfile.setVisibility(View.GONE);

		View panelSettings = findViewById(R.id.panelSettings);
		panelSettings.setVisibility(View.GONE);

		View panelPrivacy = findViewById(R.id.panelPrivacy);
		panelPrivacy.setVisibility(View.GONE);

		btnProfile.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				// DO STUFF
				View panelProfile = findViewById(R.id.panelProfile);
				panelProfile.setVisibility(View.VISIBLE);

				View panelSettings = findViewById(R.id.panelSettings);
				panelSettings.setVisibility(View.GONE);

				View panelPrivacy = findViewById(R.id.panelPrivacy);
				panelPrivacy.setVisibility(View.GONE);

			}
		});

		btnSettings.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				// DO STUFF
				View panelProfile = findViewById(R.id.panelProfile);
				panelProfile.setVisibility(View.GONE);

				View panelSettings = findViewById(R.id.panelSettings);
				panelSettings.setVisibility(View.VISIBLE);

				View panelPrivacy = findViewById(R.id.panelPrivacy);
				panelPrivacy.setVisibility(View.GONE);

			}
		});

		btnPrivacy.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				// DO STUFF
				View panelProfile = findViewById(R.id.panelProfile);
				panelProfile.setVisibility(View.GONE);

				View panelSettings = findViewById(R.id.panelSettings);
				panelSettings.setVisibility(View.GONE);

				View panelPrivacy = findViewById(R.id.panelPrivacy);
				panelPrivacy.setVisibility(View.VISIBLE);

			}
		});

	}

}

I noticed that I can not upload archives here on WordPress so I promise that I’ll soon upload the full project somewhere and add a link here. But these pieces of code that I have put here are enough for anyone who wants to have it done fast and simple.

I dare others to make a horizontal accordion. It is kinda cute and stylish 😉

Simple shape detector – Android Application

Again a little more on the apps that I am developing for my master thesis… While checking what’s new in the exergaming area and the solutions that are offered on the market I learned about interactive walls and I really liked their purpose. There are ones where a part of the wall lights and the player has to hit there and then another different part of the wall lights and the player has to hit that as soon as possible.  More about them can be read here http://www.exergamefitness.com/twall.htm  or wherever you can find on the internet.

It was all nice and great until I saw the prices of these walls… One of them was about 15k dollars which seemed too much! This is why these walls are only available in the labs or special playing rooms.  OK I am not saying that there are no such walls sold maybe all over America or other parts of the world but schools in Macedonia wouldn’t agree to buy one such wall. So I thought can’t this be somehow done using a simple mobile phone? It would cost not more than 500 dollars (if we take in consideration the most expensive smart phones on the market).  It would be available at any time and any place and there would be no need for children to go in special places intended for exergaming but they could do it whenever they feel like it…

So I started working on a mobile app that would make any white wall interactive. This should be done by sticking papers with different colors and shapes on it and make a shape detecting app.  So the first thing that I thought of was the OpenCV library and the miracles it can do but after a couple of simple tests I did on the phone that I have for testing purposes -T-Mobile Pulse I realized that I couldn’t make it real-time. This device is just not fast enough. Then I checked for some other libraries available and I found jjil – Jon’s Java Imaging Library, for mobile image processing but that didn’t help me as well. It was still not real-time…* It was time for me to read some more about shape detection. The book that helped me the most was Digital image processing – An Algorithmic introduction using Java. Having a white wall and colored shapes I went straight to the part that talked about Regions in Binary images and got couple of ideas about how current shapes can be determined. Actually the process turned out to be really simple. I think that anyone would understand when seeing this picture.

The first and last black pixels are determined and the black pixels are counted. If we compare the math formulas for areas of square, circle and triangle (a^a, a^2Π/4, a^2√3/4)  we could see that the square is more than 85%, circle between 85% and 70% and the triangle is between 70% and 55% of the area between the two pixels. After I finished writing the code doing all this simple math and did the first tests I was surprised that it worked immediately! 🙂

There is the making-of the testing wall in my room.

Here you can see a video of the app.

This app is later extended as a memory game showing the player an array of shapes that he has to remember and “hit” with the phone. ASA I have some more free time I’ll post the code on GitHub so that people having more creative ideas than me could use it. In the next posts I’ll write something more about how the testing of the apps went with primary school students.

*NOTE: I still encourage people to test this libraries further and use them since they are pretty cool! 🙂

Mobile phone applications for motivating physical activity

Since I am getting close to the end of my master thesis project named “Mobile phone applications for motivating physical activity” I decided to name my first post the same.  I am doing my last project in this area because of my childish nature and the fact that parents are neglecting their children’s physical activity. So I decided to make applications that could be used on one more device and maybe influence a bit on their behavior.

I have spent the last couple of months going through the solutions offered to the public that motivate physical activities and I am very happy that there is a lot of interest for them.  Game consoles like Sony Playstation, Xbox, Nintendo Wii, Kinect and even the good old Dance pad are projects that I really appreciate. So I started with the idea of making the phone a game controller for a game that can generally be played while sitting in front of a PC, then tried to make the phone the only device needed for the kids to play and at the end made an app that has user interface where kids/parents/players can make their own games.

I will try to describe each one of them in the future posts and give just a sneak preview in the first one in this.

Here is a youtube video showing the first presentation of one of the apps.