Tuesday, December 16, 2014

PrivyText

PrivyText is a service, which is available for three platforms: iPhone, Android and as a Website. This application provides secure, anonymous way for you to receive coupons/special offers, pay for goods & services purchase from registered PrivyText merchants, also users can get paid and text using their mobiles or from PC. 

You can use our service whenever you want to send or receive money securely and anonymously using your mobile phones or website. There is no need to carry cash, checks or credit cards. In fact PrivyText is more secure than any other way to send money currently available. When you opt in to receive advertisements, you will be getting paid for each advertisement you view which is credited to your PrivyText account. We are providing facilities to our customers to search merchants, find coupons and discounts. 

More details : www.privytext.com 



Earlier app : 


























After I joined with the PrivyText I was asked to re-design and  re-develop the whole app from zero. Therefore I have created my own design and developed the complete app within 3 months.
Now this is available on play store.


Latest app : 



















Friday, November 29, 2013

Having Fun with XNA - Game Development - Fly Me Home

XNA is a framework which provide facilities you to create your own game very easily. To work with XNA you don't need any extra knowledge about programming. Simply you just need to understand the life cycle of xna engine. after that creating your game is nothing and xna enable you to create game for xbox, PC,  as well as the windows phones.

In 2nd semester of 4th year we had a subject call GD (Game development). Under that subject there was an assignment to create a 2D game using xna. Me and my friend proffa developed a game call "Fly Me Home".
In that game user is playing as a bird. what you have to do is collect the foods withing a given time period and flying safe to home.

This is a short video of that game. :D





Android Webservices -KSOAP2 / Complex Object Types / Array

In this tutorial I'll tell you how to invoke a (SOAP) web service using android. For your knowledge I'll tell you that, when comparing with the REST and JSON, the SOAP is not the best way to exchange data with android. Anyway this post is about SOAP.So let's play with SOAP :D . You can download all source codes using the links at the bottom of the post.

Basically android does not provide any kind of SOAP library. Therefore either we have to manually create a soap request and handle it or we can use an external library. I'll choose the second approach. In this tutorial I'm going to use the KSOAP2 library. You can download it from here.

When we are talking about web services, for our purpose let's divide those services based on output.
1. Primitive type output - services which return a string , int , double ... etc
2. Complex type output - services which return a complex type object like Person{name,age,address}
3. Array of objects

Primitive type


In here what we are going to do is create a simple converter which convert Celsius to Fahrenheit.
Web service : http://www.w3schools.com/webservices/tempconvert.asmx
WSDL : http://www.w3schools.com/webservices/tempconvert.asmx?WSDL

First you have to create a new project , add buttons and text views, link those with the activity. I assumed that kind of basic things you can do easily. In my design nothing special, I just added a edit text to read the value, a button and a text view to show the result.



Now create a new activity, I named it as PrimitiveTypeActivity.  For call a soap method using ksoap we need these 4 things. You can find those information using the WSDL.
( Soap Action = Namespace + Method name )

private final String NAMESPACE="http://www.w3schools.com/webservices/";
private final String URL = "http://www.w3schools.com/webservices/tempconvert.asmx?WSDL";
private final String SOAP_ACTION="http://www.w3schools.com/webservices/CelsiusToFahrenheit";
private final String METHOD_NAME="CelsiusToFahrenheit";





After that what I'm going to do is call the web service when the button is pressed.

btnConvert.setOnClickListener(new OnClickListener() {
   
   @Override
   public void onClick(View v) {
    // TODO Auto-generated method stub
    String inputString = editTextCValue.getText().toString();
    ConvertorAsyncTask task = new ConvertorAsyncTask();
    task.execute(inputString);
   }
  });


Here you can see I'm creating a new ConvertorAsyncTask variable and call the execute function of it. When calling the execute function I'm passing the value which is read from the text view. So what is happening in ConvertorAsyncTask ?

class ConvertorAsyncTask extends AsyncTask  {
//

You can see now I extended AsyncTask class and created a new inner class. When you're calling web services you have to run the process in background. Otherwise you're activity will not responding until the response is coming . If it is not responding then the android OS will identify it and try to terminate that. Therefore we have to run those in background asynchronously.

@Override
  protected String doInBackground(String... params) {
   // TODO Auto-generated method stub

   SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
   
                        //Sending the value to service
                        PropertyInfo celPI = new PropertyInfo();
   celPI.setName("Celsius");
   celPI.setValue(params[0]);
   celPI.setType(double.class);
   request.addProperty(celPI);

   SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
     SoapEnvelope.VER11);

   envelope.dotNet = true;
   envelope.setOutputSoapObject(request);
   HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);

   try {
    androidHttpTransport.call(SOAP_ACTION, envelope);
    SoapPrimitive response = (SoapPrimitive) envelope.getResponse();
    return response.toString();
   } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   } catch (XmlPullParserException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
   return null;
  }

  @Override
  protected void onPostExecute(String result) {
   // TODO Auto-generated method stub
   if (result != null)
    textViewAnswer.setText(result + " F");
   else
    textViewAnswer.setText("Result cannot get.Please try again");

  }

 }

Enter your code inside the doInBackground method. In onPostExecute I set the result to a text view.
Before run the code remember to add the permission tag to manifet file.



That's all. :D


Complex Type

Here I'm going to tell you how to retrieve a complex type object. I created the ComplexTypeActivity for this. For the UI I just added a button and a text view to display results. Let's create the complex type class.
Here I created a class which contain 3 string values. I named it as SimpleObject.

public class SimpleObject implements KvmSerializable {

 private String name;
 private String address;
 private String id;

 public String getId() {
  return id;
 }

 public void setId(String id) {
  this.id = id;
 }

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }

 public String getAddress() {
  return address;
 }

 public void setAddress(String address) {
  this.address = address;
 }

 @Override
 public Object getProperty(int pid) {
  // TODO Auto-generated method stub
  switch (pid) {
  case 0:
   return this.id;

  case 1:
   return this.name;

  case 2:
   return this.address;
   
  default:
   break;

  }

  return null;
 }

 @Override
 public int getPropertyCount() {
  // TODO Auto-generated method stub
  return 3;
 }

 @Override
 public void getPropertyInfo(int index, Hashtable htable, PropertyInfo info) {
  // TODO Auto-generated method stub

  switch (index) {
  case 0:
   info.type = PropertyInfo.STRING_CLASS;
   info.name = "id";
   break;
  case 1:
   info.type = PropertyInfo.STRING_CLASS;
   info.name = "name";
   break;
  case 2:
   info.type = PropertyInfo.STRING_CLASS;
   info.name = "address";
   break;

  }

 }

 @Override
 public void setProperty(int index, Object value) {
  // TODO Auto-generated method stub
  switch (index) {
  case 0:
   this.id = value.toString();
   break;
  case 1:
   this.name = value.toString();
   break;
  case 2:
   this.address = value.toString();
   break;

  }

 }

}

Note that I implemented the KvmSerializable interface here. Using that interface KSOAP map those class properties with soap message.

Same as earlier I'm going to call the web service when pressed the button.
btnShowDetails.setOnClickListener(new OnClickListener() {
   
   @Override
   public void onClick(View v) {
    // TODO Auto-generated method stub
    LoadDetailsTask task = new LoadDetailsTask();
    task.execute("ID01");
   }
  });

class LoadDetailsTask extends AsyncTask {

  private final String NAMESPACE = "http://service.blog.anjula.com/";
  private final String URL = "http://112.135.137.22:8080/BlogWebService/BlogWebService?WSDL";
  private final String SOAP_ACTION = "http://service.blog.anjula.com/getDetails";
  private final String METHOD_NAME = "getDetails";

  SimpleObject result = new SimpleObject();

  @Override
  protected SimpleObject doInBackground(String... addId) {

   SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);

   PropertyInfo idListPropety = new PropertyInfo();

   idListPropety.setName("id");
   idListPropety.setValue(addId[0]);
   idListPropety.setType(addId[0].getClass());
   request.addProperty(idListPropety);

   SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
     SoapEnvelope.VER11);

   // envelope.dotNet = true;
   envelope.setOutputSoapObject(request);

   envelope.addMapping(NAMESPACE, "SimpleObject",
     new SimpleObject().getClass());

   HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);

   try {
    androidHttpTransport.debug = true;
    androidHttpTransport.call(SOAP_ACTION, envelope);
    SoapObject response = (SoapObject) envelope.getResponse();

    result.setId(response.getProperty("id").toString());
    result.setName(response.getProperty("name").toString());
    result.setAddress(response.getProperty("address").toString());

    return result;

   } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   } catch (XmlPullParserException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }

   return null;

  }

  @Override
  protected void onPostExecute(SimpleObject result) {
   // TODO Auto-generated method stub
   if (result != null)
    textViewResult.setText("Id: " + result.getId() + "\nName: "
      + result.getName() + "\nAddress: "
      + result.getAddress());
  }

 }
//

Here you can see I'm mapping the out put using field names.

result.setId(response.getProperty("id").toString());
    result.setName(response.getProperty("name").toString());
    result.setAddress(response.getProperty("address").toString());

In URL I entered my IP address there, because I ran the service in my computer. Therefore you have to change that IP address to your IP address if you're running the server application in your computer.
After you pressed the button the program will invoke this method.

public SimpleObject getDetails(String id){
        SimpleObject result = new SimpleObject();        
        result.setId(id);
        result.setName("Anjula");
        result.setAddress("Kaduwela");        
        return result;        
    }

That's all :D

Array of Objects

Here I'm using the same complex type class which I mentioned above. My activity name is ArrayTypeActivity. 



class LoadDetailsTask extends AsyncTask {

  private final String NAMESPACE = "http://service.blog.anjula.com/";
  private final String URL = "http://112.135.137.22:8080/BlogWebService/BlogWebService?WSDL";
  private final String SOAP_ACTION = "http://service.blog.anjula.com/getArrayDetails";
  private final String METHOD_NAME = "getArrayDetails";
  SimpleObject result[] = new SimpleObject[3];

  @Override
  protected SimpleObject[] doInBackground(String... idList) {

   SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
   PropertyInfo idListPropety = new PropertyInfo();  
   idListPropety.setName("id");
   idListPropety.setValue(idList[0]);
   idListPropety.setType(idList[0].getClass());
   request.addProperty(idListPropety);
   
   SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
     SoapEnvelope.VER11);

   // envelope.dotNet = true;
   envelope.setOutputSoapObject(request);

   envelope.addMapping(NAMESPACE, "SimpleObject",
     new SimpleObject().getClass());

   HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);

   try {
    androidHttpTransport.debug = true;
    androidHttpTransport.call(SOAP_ACTION, envelope);

    Vector response = (Vector) envelope
      .getResponse();

    for (int i = 0; i < response.size(); i++) {
     SoapObject tempObject = response.get(i);
     if (tempObject != null) {
      SimpleObject temp = new SimpleObject();
      temp.setId(tempObject.getProperty("id").toString());
      temp.setName(tempObject.getProperty("name").toString());
      temp.setAddress(tempObject.getProperty("address")
        .toString());
      result[i] = temp;
     }
    }

    // SoapPrimitive response = (SoapPrimitive)
    // envelope.getResponse();

    return result;

   } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   } catch (XmlPullParserException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }

   return null;

  }

  @Override
  protected void onPostExecute(SimpleObject[] result) {
   // TODO Auto-generated method stub
   // super.onPostExecute(result);
   String text = "";
   if (result == null) {
    Log.d("NULL", "This is null");
   } else {
    for (int i = 0; i < result.length; i++) {
     if (result[i] != null) {
      
      text=text+"Id: " + result[i].getId() + "\nName: "
        + result[i].getName() + "\nAddress: "
        + result[i].getAddress()+"\n";

     }
    }
    textViewResult.setText(text);
   }

  }

 }

//

Here note that instead of retrieving a single object we are retrieving an array of objects. So we have to handle that using Vectors.
Vector response = (Vector) envelope
      .getResponse();

    for (int i = 0; i < response.size(); i++) {
     SoapObject tempObject = response.get(i);
     if (tempObject != null) {
      SimpleObject temp = new SimpleObject();
      temp.setId(tempObject.getProperty("id").toString());
      temp.setName(tempObject.getProperty("name").toString());
      temp.setAddress(tempObject.getProperty("address")
        .toString());
      result[i] = temp;
     }
    }
//



You can download web service from (Netbeans) here and to download the android source code (eclipse) click here. 

Saturday, November 16, 2013

The Seeker - Mobile Security App

When we were in 3rd year in SLIIT there was a subject called MAD - Mobile Application Development. Under that subject we learned iPhone app and android app development. Under MAD we had to develop a n app using android & ios. For that we developed two different applications. Using ios Proffa(Krishantha) developed a puzzle game and for android I developed a mobile security application called "The Seeker" .

The seeker is working based on commands received using SMS messages. Of course, you can customize those commands. In this version (1.1) I created only several basic security functions. In later versions I'm going to  implement this with more features.

SIM
In this function rather than the codes you have to mention a trusted mobile number. If the SIM is changed the app will automatically send you the new SIM number and other details. If you want you can get IMEI or the SIM number using the codes at any time.

GPS
After you activated this function, the app will send you the coordinates of the current location where the phone is.This will send a message in every 3 minutes until you send the code again and disable that feature.

ALARM
Using this function you can ring an alarm. This alarm can be stopped only by sending the code again.

LOCK
This will lock your device, even the user unlock it by using your pattern or pin automatically again it will locked. To unlock you have to send the code again.

WIPE
Simple to wipe all your data this function can be used. To wipe all data several minutes will taken. This time is depending on the device.

The Seeker is now available in Google Play.


You can see a demonstration video below.