Coming Along Good!

The new version of bbpointofsale.com is almost ready. It is now a java application instead of a web-based application. It integrates with a card swipe and receipt printer machine that doesn’t cost much. Besides those two things not much has changed.

KSoap with PHP Tutorial

This post is for:
You: developing a BlackBerry application in KSoap2 with PHP as the server

If that doesn’t describe you, don’t read this post!
If that does describe you, hope you enjoy!

The first step is to preverify your KSoap jar file. Copy ksoap2-j2me-core-2.1.2.jar to C:\Program Files\Eclipse\plugins\net.rim.eide.componentpack4.5.0_4.5.0.16\components\bin

Make sure the JDK is in your PATH environment varaible.

Then run:

preverify -classpath "JDE_PATH_HERE\lib\net_rim_api.jar" "ksoap2-j2me-core-2.1.2.jar"

Preverify put a new jar into an “output” directory in that folder. Copy that to where you put the original jar.

Now add that jar in your eclipse project by clicking on your project properties and going to “Java Build Path” – make sure you click on “Order and Export” and check the box that tells it to export it.

Well here’s where the rubber meets the road, you need KSoap to talk to PHP. I created a “Service” class which handles all the communication with the server:

import java.io.IOException;
 
import org.ksoap2.SoapEnvelope;
import org.ksoap2.SoapFault;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransport;
import org.xmlpull.v1.XmlPullParserException;
 
public class Service {
	public static final String action = "http://keyringlabs.com/Login";
	public static final String namespaceRoot = "keyringlabs.com";
	public static final String webroot = "http://192.168.1.2/bbpointofsale.com/";
 
	public String errorMessage;
	public String key;
	public String transactionID;
	private HttpTransport transport;
	private SoapSerializationEnvelope envelope;
 
	public Service() {
		transport = new HttpTransport(webroot + "bb/service/index.php");
		transport.debug = true;
		envelope = new SoapSerializationEnvelope(SoapEnvelope.VER10);
		key = null;
	}

A request is made by setting parameters and getting back a parameter, getting back more than one parameter is left as an exercise for the reader. Here’s what I’ve done:

public boolean ProcessLogin(String email, String password) {
	System.err.println("ProcessLogin");
 
	errorMessage = "";
 
	String namespace = "urn:" + namespaceRoot + ":login";
 
	SoapObject message = new SoapObject(namespace, "login");
 
	message.addProperty("email", email);
	message.addProperty("password", password);
 
	envelope.bodyOut = message;
 
	String soapAction = namespace + "#login";
 
	try {
		transport.call(soapAction, envelope);
	} catch (IOException e) {
		e.printStackTrace();
		System.out.println("error: "+e.getMessage());
		errorMessage = e.getMessage();
		System.out.println("response: "+transport.responseDump);
		return false;
	} catch (XmlPullParserException e) {
		e.printStackTrace();
		errorMessage = e.getMessage();
		System.out.println("response: "+transport.responseDump);
		return false;
	}
 
	try {
		SoapObject result = (SoapObject) ((SoapObject)envelope.getResponse()).getProperty(0);
 
		key = hackToGetResponse("serviceToken", result.toString());
 
		if (key.length() > 0) {
			System.out.println("KEY:" + key);
			return true;
		} else {
 
		}
	} catch (SoapFault e) {
		errorMessage = e.getMessage();
		System.out.println("response: "+transport.responseDump);
		return false;
	} catch (Exception e) {
		errorMessage = e.getMessage();
		System.err.println("response: "+transport.responseDump);
		return false;
	}
 
	return false;
}

hackToGetResponse is necessary because the return of the PHP page the request is sent to is difficult to get at through KSoap. This is hackToGetResponse:

public String hackToGetResponse(String key, String response) {
	System.out.println("hackToGetResponse:" + response);
	String start = "anyType{key=" + key + "; value=";
	String end = "; }";
 
	if (response.indexOf(start) == -1 ||
		response.indexOf(end) == -1) return "";
 
	System.out.println("hackToGetResponse:" + "response.substring(0, " + response.indexOf(start)  + ").substring(0, " + response.indexOf(end) + ");");
	response = response.substring(response.indexOf(start) + start.length());
	response = response.substring(0, response.indexOf(end));
 
	if (response.indexOf("anyType{}") != -1) return "";
 
	return response;
}

And finally, the PHP code:

<?php
 
$server = new SoapServer(null, array('uri' => "urn:keyringlabs.com"));
 
$server->addFunction("login");
 
function login($email, $pass) {
	if (strlen($email) == 0) {
		return Array('serviceToken' => '');
	} elseif (strlen($pass) == 0) {
		return Array('serviceToken' => '');
	} else {
		$objMerchant = Merchant::LoadByEmailPassword($email, $pass);
		if ($objMerchant == null || $objMerchant->Id < 1) {
			return Array('serviceToken' => '');
		} else {
			$key = uniqid();
			$objSess = new Merchantsessions();
			$objSess->MerchantID = $objMerchant->Id;
			$objSess->ServiceToken = $key;
			$objSess->Save();
		}
	}
 
	$result = Array('serviceToken' => $key);
	return $result;
}
 

That’s it, a BlackBerry application that communicates with a PHP application with very little legwork. I hope this is useful to some people, it was a long journey for me to arrive at this code.

When I have some time I will make the Service class multi-threaded (as it should be being that it does network connections), I will post an update here when I’ve done that.

Card Swipe

Hard at work on a new version of the BlackBerry Point of Sale system which will integrate with a mobile card swipe and receipt printer combination machine. Found a supplier that has good machines for a good price. I am thinking about posting a tutorial here on my experience developing a java application for the BlackBerry when it is complete.