Friday, August 17, 2012

Simple Collision Detection in 2D

The title of this post starts with "simple" because we can complicate it a lot. This is a very simple explanation of the collision detection.

The collision detection is used in graphical applications like games to know whether an object hit another object, like the character of the game against a wall or against other object. If this happens the character should stop, die, exploit...

It's quite important to make this part of the game precise and efficient, because it can ruin a game if it's not precise (the game loose a lot of of reality) and also if it's not efficient (it will slow the game).

Let's start by the shapes. We are going to use simple shapes. Points (x,y), Rectangles and Circles.

To define a rectangle we could use 2 points: the lower left and the upper right

Or 1 point (lower left) and the width and height


To define a circle we will use the center point and the radius.


If we have 2 circles how could we know if they are overlapping one each other?
Just checking the distance between the two centers. If the distance is minor than the addition of the two radius, is because we have an overlap. If it's bigger we don't have overlap.

It seems easy, but how can we calculate the distance between two points?
Remembering the vectors of the math class, if we have two points:

A-------------------------->B

distance is the square root of the square of the difference of each coordinate.??

difX = B.x - A.x
difY = B.y - A.y

Dist = sqrt(difX*difX + difY*difY)

So we just have to check if this distance is minor than the addition of the radius. Easy. But we can do it better cos we know that the sqrt function is very expensive. So we can avoid it checking if the squared distance is minor than the square of the addition of the radius.

public float distanceSquare(Point a, Point b){
  //use distance square to avoid use square root cos is expensive
  float x = b.x - a.x;
  float y = b.y - a.y;
  return x*x + y*y;
 }

public boolean circle2cirlce(Circle a, Circle b){
  float sumRad = a.radius + b.radius;
  return distanceSquare(a.center, b.center) < sumRad*sumRad;
 }

That was really easy, but what if we have two rectangles? If we think a little about it, we can find a solution. But there is the Separating Axis Theorem SAT to help us. The theorem says that if two convex polygons are not overlapping, we can draw a line between them. Then using an axis that will be the normal of this line we can get the projection of the shapes in the axis and see that the projections do not overlap. Well is a quick explanation. If you want to know more about it just search Separating Axis Theorem on the Internet.

That theorem is very good to check collisions between polygons, because you just have to check the projections on the axis. One polygon has the same number of axis that of  vertices's. And when you find two projections that don't overlap, you can finish the check. That makes this method very efficient.
But we are using a simple version of polygon. We are using rectangles. And they are always aligned with the axis X and Y.  So for us should be much more easy. We just need 2 axis cos the projections are the same in the other two.


In this image we can see the projections in the axis. In this concrete case we could use x and y.

So one first approximation to the method to check if two rectangles are overlapping could be:

public boolean rectWithRectProjection(Rectangle a, Rectangle b){
  float minX, maxX, minY, maxY;
  
  //axis x (1,0)
  minX = Math.min(a.downLeft.x, b.downLeft.x);
 
  maxX = Math.max(a.downLeft.x+a.width, b.downLeft.x +b.width);
  
  if(a.width + b.width < maxX - minX)
   return false;
  //axis y (0,1)
  minY = Math.min(a.downLeft.y , b.downLeft.y);
  
  maxY = Math.max(a.downLeft.y+a.height, b.downLeft.y+b.height);
  
  if (a.height+b.height < maxY - minY)
   return false;
  
  return true;
  
 }

In this case we are used the version that gives the width and the height of the rectangle.
This method is slow because uses the min and max functions that are very expensive. We can do it better just getting the points that can be overlapped in each case. Let's see how two rectangles can be overlapped. Depending on the side that is each one.





To avoid using max and min functions, we can just check this 4 possibilities. One for each axis of the rectangle. If we use the 2 points version of the rectangles we can write it like:

public static boolean rectWithRect(Rectangle2Points a, Rectangle2Points b){
  return (a.downLeft.x <= b.upRight.x && 
   a.upRight.x >= b.downLeft.x && 
   a.downLeft.y <= b.upRight.y &&
   a.upRight.y >= b.downLeft.y);
  
 }

In this case we just check two points in each condition. This version is much more efficient. In each condition we are checking one axis (one side of the rectangle) left, right, bottom, top. Notice that all the conditions must be true. If one of this conditions is false we can assure that the rectangles are not colliding. So knowing this we can make this checking faster in some cases:

public static boolean rectWithRectCut(Rectangle2Points a, Rectangle2Points b){
  if(a.downLeft.x > b.upRight.x)
   return false;
  if(a.upRight.x < b.downLeft.x)
   return false;
  if(a.downLeft.y > b.upRight.y)
   return false;
  if(a.upRight.y < b.downLeft.y)
   return false;
  
  return true;
 }

We need to invert the major/minor operators cos now we are checking if not meet the condition. You can use NOT (!) instead if you want, of course.

Using the other version of rectangle it would be:

public static boolean rectWithRect(RectanglePointWH a, RectanglePointWH b){
  return (a.downLeft.x <= b.downLeft.x + b.width && a.downLeft.x + a.width >= b.downLeft.x &&
    a.downLeft.y <= b.downLeft.y + b.height && a.downLeft.y + a.height >= b.downLeft.y);
  
 }
 
 
 //FASTEST
 public static boolean rectWithRectCut(RectanglePointWH a, RectanglePointWH b){
  if(a.downLeft.x > b.downLeft.x + b.width)
   return false;
  if(a.downLeft.x + a.width < b.downLeft.x)
   return false;
  if(a.downLeft.y > b.downLeft.y + b.height)
   return false;
  if(a.downLeft.y + a.height < b.downLeft.y)
   return false;
  return true;
 }


Getting the time of these algorithms with two rectangles not overlapping

PROJECTION
 COLLISION NOT FOUND
Time:166993

NOT CUT
 COLLISION NOT FOUND
Time:18404

CUT
 COLLISION NOT FOUND
Time:2170

We can see that it's a big difference. Of course this difference between the NOT CUT algorithm and the CUT will only happen when the rectangles are not colliding, cos when we find that the rectangles are not colliding we finish the algorithm. But the good news are that in a game we usually have lots of objects and very few colliding. So considering this difference for every object in the game on every frame... it could be important.



If we want to check if a single point is overlapping a rectangle, the logic is quite similar. I'm not going to write the code here.


Now let's think how can we detect collisions between circles and rectangles. The first attempt is to use a similar algorithm than the one used to check two rectangles. And it could work in most of the cases, but not in all of them. Why? Because if we use the same algorithm we are treating the circle as if it  were a square with the diameter as a side. Think in this case



Here we can see that if we consider the circle as a square, we have a collision. But it's a fake collision. Its cos this algorithm is not precise. So we need to change the algorithm to check this. One way to do this is find the closest point of the rectangle to the circle, and then check if the distance from this point to the center of the circle is bigger than the radius. But how can we find this closest point? 


Yes, another time we have to check the axis. If the Y coordinate of the center of the circle is into the space used by the rectangle (look at the right circle), we have to use the Y coordinate of the circle to the Y of the closest point. Otherwise we will use the biggest or the fewest Y coord of the rectangle (depending if the circle is up or down). The same with the X. Once we have the X and Y of the closest point we can check the distance. Ah, remember that if we check the distance squared is more efficient.

public static boolean colisioCercleRectangle(Circle c, Rectangle2Points r) {
      Point closest;
         float closestX = c.center.x;
         float closestY = c.center.y;
         
         if(c.center.x < r.downLeft.x) {
             closestX = r.downLeft.x; 
         } 
         else if(c.center.x > r.upRight.x) {
             closestX = r.upRight.x;
         }
           
         if(c.center.y < r.downLeft.y) {
             closestY = r.downLeft.y;
         } 
         else if(c.center.y > r.upRight.y) {
             closestY = r.upRight.y;
         }
         
         System.out.println(" closest x:"+closestX+" closesty:"+closestY);
         closest = new Point(closestX,closestY);
         
         
         return distanceSquare(c.center,closest) < c.radius * c.radius;           
     }

Well I think that's all. I just want to say that this is a very simple way to do this. We are using circles and rectangles, and the rectangles are always parallel to the axis X and Y. And of course in 3D the things are much more difficult. But this can work for a simple 2D game.

Wednesday, August 15, 2012

REST ATHENTICATION AND SIGN REQUEST USING OAUTH

In this post I'm going to explain a little how to use OAuth to Authenticate for using a REST API. In former post we used the twitter API to make a REST client application in android, but without authenticate. We need authentication to make some request, like send a tweet.

There are some ways to authenticate but Twitter uses Oauth version 1. Using OAuth we don't need to store any user/password. The user allows our app to make some things in his/her account. And our app delegates the authentication and authorization to a trusted location (in this case Twitter). Our app just has to store two tokens and sign each request to the API. The authorization has a life time in OAuth, but Twitter authorizations are unlimited, but, of course, the user can always revoke the using twitter web page.

To help us with all the authorization flow with OAuth we are going to use signpost library. 
So we will need to add signpost-commons-http4-1.2.1.2.jar (cos we are going to work with apache libraries in android) and signpost-core1.2.1.2.jar.

So the flow to authorize an application using signpost is:
  • First we need to create the twitter application on the twitter developers site. Once created we should have some information:
  • Consumer key
  • Consumer secret
  • Request token URL
  • Authorize URL
  • Access Token URL
  • Callback URL   (is the URL to redirect once authorized, but don' worry about that, use what you want, we will pass another through the flow)
  • With the key and the secret we can create an OAuthConsumer object wich will represent our application. With the URLs we can create an OAuthProvider object which will represent Twitter in this case.
  • With these two objects we can get retrieve a request token. This is the URL where the user has to authenticate and authorizate. 
  • Using that URL we have to pop the browser and wait until the user authorize the app.
  • Then we will intercept the callback from twitter and get some information (oauth verifier).
  • With the verifier we can get retrieve the access token (token and tokensecret) from twitter and store them (in Shared Preferences) to be able to sign further requests to the API.
As usual, each task that means download information from the Internet shouldn't be executed in the UI thread. To do this we can use AsyncTasks.

Well, knowing the "simple" OAuth flow and with the application created on the twitter developers site we can start to write.

The main activity will show a TextView to see if the user is authenticated or not, a button to erase the credentials, a button to send a tweet, a EditText to write the text to send and a TextView to see the result of the send (OK or KO). The send button and the edit text should are invisible if the user is not authenticated. The layout looks like this when the user is authenticated.



The main activity will check the Shared Preferences to see if we already have the tokens in onResume(). If we don't have tokens yet, we will launch an Activity to start the authorization flow. If we have tokens we have to put these tokens in our OAuthConsumer object and we can sign requests (later we'll see how).

private void checkTokens() {
  String token = shPref.getString(TwitterOauthKeys.TOKEN_KEY, "isnull");
   String tokensecret = shPref.getString(TwitterOauthKeys.TOKEN_SECRET_KEY, "isnull");
   
   if(token.equals("isnull")){
    text.setText("User NOT Authenticated");
    //disable buttonsend and company
    buttonsend.setVisibility(View.GONE);
    texttweet.setVisibility(View.GONE);
    //launch activity NewTwitterClientActivity to get tokens
    try {
    Intent NewClientIntent = new Intent(this, Class.forName("com.vidaltech.rest.oauth.NewTwitterClientActivity"));
    startActivity(NewClientIntent);
   } catch (ClassNotFoundException e) {
    Log.e(TAG,"Activity class not found");
   }
   }
   else{
    text.setText("User Authenticated!");
    //enable button send and edittext
    buttonsend.setVisibility(View.VISIBLE);
    texttweet.setVisibility(View.VISIBLE);
    
    //put tokens in OauthConsumer to sign requests
    consumer.setTokenWithSecret(token, tokensecret);
    
    
   }
   
 }


In the New Twitter Client Activity we need to create the OAuth objects and launch the task to retrieve the request token passing the objects to the task, as we've seen on the flow.

/*
    * Start a task to retrieve request token and launch browser/webview
    */
   new RetrieveRequestTokenTask(this, oauthConsumer, oauthProvider).execute();

This task simply retrieve the URL using the signpost library and launch a browser. Here we can see the doInBackground method of the task

protected Void doInBackground(Void... params) {
  try{
   /*
    * Getting the URL to redirect the user to authorize the application (request Token URL)
    */
  String url = oauthProvider.retrieveRequestToken(oauthConsumer, TwitterOauthKeys.CALLBACK_URL);
  Log.d(TAG,"Retrieved request token url "+url);
  /*
   * Redirecting user:
   * -creating a intent to launch browser
   * We use operator or to set various flags in the same int
   * flag no history to mark the new activity to be finished inmediately after user ends
   * flag from background to indicate that is launched from a background task, not from the interaction with user
   */
  Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)).setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_FROM_BACKGROUND);
  context.startActivity(browserIntent);
  
  }
  catch(Exception e){
   Log.e(TAG, "Error retrieving request token.");
   
  }
  return null;
 }

Now the browser should open and show the page to authenticate (if the user is not already logged in) and the page to authorize.

There is another possibility for doing this. We can use a WebView to show the Authentication/Authorization page in our application without launching the browser. At the end of the post you can see the details.

After that, we have to intercept the callback in our application. To do this we need to create a intent-filter. Each filter describes a capability of the component, a set of intents that the component is willing to receive. Check the android developer page to get more information about this.

<activity android:configChanges="keyboard|keyboardHidden|orientation" android:name="NewTwitterClientActivity" android:launchMode="singleInstance">
            <intent-filter>
                <action android:name="android.intent.action.VIEW"/>
                <category android:name="android.intent.category.DEFAULT"/>
                <category android:name="android.intent.category.BROWSABLE"/>
                <data  android:scheme="vidaltech" android:host="twitter"/>
            </intent-filter>
        </activity>

In the data tag, scheme and host must be the same that the callback URL we used in our app. The one that we used to build the OAuthProvider object. For example in this case is "vidaltech://twitter".

Now, following the flow, we can override the method onNewIntent(Intent intent) in that activity to get the URI and use it to retrieve the access token (in a separate task).

@Override
 protected void onNewIntent(Intent intent) {
  super.onNewIntent(intent);
  Log.d(TAGLIFE, "NEWCLIENTACTIVITY ONNEWINTENT");
  Log.d(TAG, "enter onNewIntent");
  final Uri uri = intent.getData();
  Log.d(TAG, "enter onNewIntent"+uri.getScheme());
  if(uri != null && TwitterOauthKeys.CALLBACK_URL.startsWith(uri.getScheme())){
   /*
    * launch the task to retrieve access token
    */
   new RetrieveAccesTokenTask(this,oauthConsumer, oauthProvider, shPref).execute(uri);
  }
  finish();
  
 }

In the retrieve acces token task we have to retrieve the tokens and store them in Shared Preferences.

@Override
 protected Void doInBackground(Uri... params) {
  Uri uri = params[0];
  //extract the oauth verifier from Uri using the static strings from OAuth class
  String oauthVerifier = uri.getQueryParameter(OAuth.OAUTH_VERIFIER);
  //launch the method to retrieve access token
  try {
   oauthProvider.retrieveAccessToken(oauthConsumer, oauthVerifier);
   /*
    * now we should have the token and tokensecret in oauthConsumer
    * Let's store them in shared preferences: we should use a Editor to write in sharedpreferences
    * with putString and then commit
    */
   Editor shPrefEditor = shPref.edit();
   shPrefEditor.putString(TwitterOauthKeys.TOKEN_KEY, oauthConsumer.getToken());
   shPrefEditor.putString(TwitterOauthKeys.TOKEN_SECRET_KEY, oauthConsumer.getTokenSecret());
   shPrefEditor.commit();
   
  } catch (OAuthMessageSignerException e) {
   Log.e(TAG, "Signer execption");
  } catch (OAuthNotAuthorizedException e) {
   Log.e(TAG, "Not autorized");
  } catch (OAuthExpectationFailedException e) {
   Log.e(TAG, "Expectation failed");
  } catch (OAuthCommunicationException e) {
   Log.e(TAG, "Communication error");
  }
  return null;
 }

In this moment we have our application authorized. Now let's see how to sign a request. To do this let's tweet somewhat. First we can check the twitter developers page to see which request we need to do. To tweet we have to do this POST request: POST statuses/update. 
Following the link we can see that the URL is http://api.twitter.com/1/statuses/update.format and we only have one required parameter: "status". This parameter is the message we want to send URL encoded.

So, do you remember that we have a send button and a edit text field in our layout? Let's use them. When the authenticated user push the button, we have to launch a task to make the REST request. And we already know how to do this with a GET method. Now we are going to use POST method, but is quite similar. Ah! And remember to sign the request before execute it!

First we have to create the HttpPost object with the URL. Then we have to add the data (message) using a NameValuePair object (from Apache library). Then sign the request (using our OAuthConsumer object) and that's all.

this.hPost = new HttpPost(uri);
  
  //put the data in a namevaluepair (from apache library)
  List dataToAdd = new ArrayList(1);
  
  dataToAdd.add(new BasicNameValuePair("status",data));
  
 
   hPost.setEntity(new UrlEncodedFormEntity(dataToAdd));
   
   /*
    * Before send we have to SING the request
    */
   
    consumer.sign(hPost);
   
   
   HttpResponse response = this.httpClient.execute(hPost);
   
   
   StatusLine statusLine = response.getStatusLine();
   if (statusLine.getStatusCode() == 200){
    Log.d(TAG, "post return OK");
    return true;
   }
   else{
    Log.d(TAG, "post return KO");
    return false;
   }

Take care with the Exceptions! Of course that is executed in an asynchronous task and at the end it will update the UI showing wether the tweet has been sent or not.


USING A WEBVIEW INSTEAD OF LAUNCHING A BROWSER

A WebView is a widget that allows to load web pages in our application.
Using a webview our app will be more clean and we will have more control on the authorization process.

So let's go.

First of all we don't need anymore the intent-filter and the method onNewIntent of the New Client Activity. In fact we don't need that activity, cos now we are going to intercept the callback using a WebViewClient.

A WebViewClient allows to control the events happening in a WebView. So we are going to use this to know when is loading a page. We will check if the page loaded is our CALLBACK URL and then we get the params from the URL to pass them to the RetrieveAccesTask.

So now, the RetrieveRequestTask won't launch a browser. Now will launch an activity which has a WebView in the layout. And we are going to pas the url to load using the method puExtra if the Intent.

Intent webViewIntent = new Intent(this.context, Class.forName("com.vidaltech.oauth.webview.WebViewActivity"));
  webViewIntent.putExtra("url", url);
  context.startActivity(webViewIntent);
  

We get the url from the intent.
Intent intent = getIntent();
        url = intent.getStringExtra("url");

This activity will have a WebView object and we will set a ClientWebView to be able to call to onPageStarted method. In this method we will get the url and call the Retrieve Acces Task
 webView = (WebView) findViewById(R.id.webview);
        WebSettings webSettings = webView.getSettings();
        webSettings.setJavaScriptEnabled(true);
        //webSettings.setBuiltInZoomControls(false);
        
        
        webView.setWebViewClient(new WebViewClient(){//Web client allow us to get control of the events

         /*
          * We have to use onPageStarted. Is called once.
          * onResource
          */

   @Override
   public void onPageStarted(WebView view, String url, Bitmap favicon) {
    Log.d(TAG," on pagestarted url "+url);
    
    if(url != null && url.startsWith(TwitterOauthKeys.CALLBACK_URL)){

     /*
      * here we have in the url with oauth_verifier
      * We just need to encode and use the task already created
      */

     Log.d(TAG," on pagestarted into if");
     
     Uri uri = Uri.parse(url);
     new RetrieveAccesTokenTask(context,TwitterOauthKeys.oauthConsumer, TwitterOauthKeys.oauthProvider, shPref).execute(uri);
     
     callFinish();//finish the activity
    }
    else{
      //Check if we already have the tokens cos always is called onPageStarted
      String token = shPref.getString(TwitterOauthKeys.TOKEN_KEY, "isnull");
     
      //if we have the tokens we can close this activity and go back to the main activity
      if(!token.equals("isnull")){
       callFinish();//finish the activity
      }
     }
    
   }
         
        });
        
        webView.loadUrl(url);
 
As we can see, we need to check if we have the tokens in this activity (also in the main activity) in the method onPageStarted. If we have the tokens we can finish the activity to go back to the main activity and send tweets.

We have also to store the OAuthObjects in another class to be able to acces them from the differents activities.


Sunday, August 12, 2012

Asyncronous tasks in android

Hi there, in this entry I'm going to talk about the famous AsyncTasks.

If you want to do some process that could take a while (like download something) and you are using the User Interface thread to do that, your UI will be blocked while doing that process, and that is very annoying for the user. That's not a good design. When the application is doing some process at least it should show some kind of information about what is happening, like a progress dialog showing how long it will take. To do that we have to use threads so while the UI is showing something, the thread is doing his work and updating the UI (for example with the percentage of the process or adding information).

The problem in Android is that the UI thread doesn't allow calls from other threads (for security matters?). So if you are in other thread and you need to update something you cannot simply call a method.

There are some methods to do this (use a Handler, runOnUiThread, AsyncTask) but the most used is AsyncTask because is simple and easy.

An AsyncTask uses three generic types

public class MyAsyncTask extends AsyncTask<Params, Process, Result>  

Params is the type of data that we are going to pass to the task.
Process is the type of data that we are going to pass to the update process method.
Result is the type of data that the task is going to return.

If we are not going to use one of them we have to use the Void type.

The AsynkTask has one method that you have to override

protected Object doInBackground(Object... params) 

This method is launched in other thread. Here we have to do the long process.

The other methods that you can override will help you to update information between threads. They are

@Override
 protected void onPostExecute(Object result) {
  
 }

 @Override
 protected void onPreExecute() {
  
 }

 @Override
 protected void onProgressUpdate(Object... values) {
  
 }

 @Override
 protected void onCancelled() {

 }

onPreExecute is executed before doInBackground and you can use it for make some changes to UI, like show a dialog or disable some views.

onProgressUpdate is the method used to update the progress. It will be called from doInBackground.

onPostExecute will be executed once finished doInBackground. We can use it to dismiss the dialog or to update the information in the UI.

onCancelled will be executed if the task is cancelled.

Knowing how AsyncTask works we can make an asyncronous task that download information from a REST resource to take advantage of the example in the former entry.

We are not going to use the onProgressUpdate method in this example, and we have to pass the URI (a String) to access to the REST service and the task will return the information in a String.

public class MainTwitterClientActivity extends Activity implements OnClickListener{
 private static final String URI = "http://twitter.com/statuses/user_timeline.json?id=xxxxxx";
 private HttpRestConnector restConnector;
 
 private TextView text;
 private Button buttonSend;
 
 
 
 
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        restConnector = new HttpRestConnectorJson();
        
        buttonSend = (Button) findViewById(R.id.button1);
        
        text = (TextView) findViewById(R.id.editText1);
        
        buttonSend.setOnClickListener(this);
  
    }



 public void onClick(View v) {
  
  new DialogProgressTask(this).execute(URI);
  
 }
 
 public void setText(String t){
  text.setText(t);
 }
    
 private class DialogProgressTask extends AsyncTask{
  private ProgressDialog dialog;
  private Context context;
 
  
  public DialogProgressTask(Context context){
   this.context = context;
  }
  @Override
  protected void onPreExecute() {
   dialog = ProgressDialog.show(this.context, "Downloading", "Downloading information from Twitter...",true);
  }

  @Override
  protected String doInBackground(String... uri) {
   
   return JsonParserTwitter.getInfFromArray(restConnector.execGetConnection(uri[0]));
  }

  
  @Override
  protected void onPostExecute(String result) {
   
   dialog.dismiss();
   setText(result);   
  }

 }

}


In the doInBackground method we just call the REST service using the custom class RestConnector and pass the result to a JSON parser class to get the information in String. Then we use this String in onPostExecute method to call the method "setText" to update the UI showing the information downloaded.

As we can see AsyncTask is simple and very useful.

REST with JSON - part 1

In this entry of the blog I want to explain how to consume RESTful web services from an Android application using the format JSON for the information.

The term REST stands for Representational State Transfer. REST is not a technology, and many tools available on the market might not support REST directly because of the lack of a specific standard. What makes REST the best choice in many scenarios, is its ease of implementation and the fact that REST is not tied to any particular system, language or tool. If you can send an HTTP request to a web server, you can use REST.

To define what should be done on a specific resource, REST uses the intrinsic meaning of the verbs of the http protocol. Here are the five main verbs that are commonly used in RESTful systems:
  • GET - Retrieve a resource
  • PUT - Create a resource
  • POST - Update a resource
  • DELETE - Delete a resource
  • HEAD - Retrieve the metadata that defines a resource

If we don't want to create our REST service in a web/application server we can use one of the thousands of services available on the Internet. For instance Twitter.

To retrieve the user timeline of  Joel Comm the author of the book Twitter Power, we can access the uri:
http://twitter.com/statuses/user_timeline/joelcomm.json

And it will return the user timeline in JSON format. You can try it in your browser. If you are using Firefox there is a tool called RESTClient that helps you viewing the information of the REST services.

Of course Twitter has much more resources published. You can see them here.
Some of the resources are not accessible without authentication, but in this part we are going to use only resources that don't need authentication.

To make this in android we need to have an application with INTERNET permission. In the manifest:
<uses-permission android:name="android.permission.INTERNET"/>

This application has to create a Http Get method, execute it and get the response. The information will be in a HttpEntity object.

                
StringBUilder sBuffer = new StringBuilder();
HttpClient httpClient = new DefaultHttpClient();
  HttpGet hget = new HttpGet(URI);
  hget.addHeader("accept", FORMAT);
  
  try {
   HttpResponse response = httpClient.execute(hget);
   StatusLine statusLine = response.getStatusLine();
   if (statusLine.getStatusCode() == 200){
    //deal with the entity
    HttpEntity entity = response.getEntity();
    InputStream content = entity.getContent();
    BufferedReader bReader = new BufferedReader(new InputStreamReader(content));
    String line;
    while((line = bReader.readLine()) != null)
     sBuffer.append(line);
    
   }
   else{
    Log.e(TAG,"Error downloading data ");
    
   }
   
  } catch (ClientProtocolException e) {
   Log.e(TAG, "Error client protocol bad");
   e.printStackTrace();
   
   
  } catch (IOException e) {
   Log.e(TAG, "Error io execption");
   e.printStackTrace();
   
  }
  
  String resultInJsonFormat = sBuffer.toString();
 

To extract the information from the Entity we can use alternatively the toString(HttpEntity) method of EntityUtils

String resultInJsonFormat = EntityUtils.toString(entity);

As you know, if you get information from the Internet, it could be a little slow. So you shouldn't use the User Interface thread to do this kind of things because while is downloading information the UI will remain blocked (and it doesn't likes to the users). But we'll see how to do that in a further entry...

Now that we have the information in JSON format let's see what's that. Wikipedia says that JSON , or JavaScript Object Notation, is a text-based open standard designed for human-readable data interchange. It is derived from the JavaScript scripting language for representing simple data structures and associative arrays, called objects. Despite its relationship to JavaScript, it is language-independent, with parsers available for many languages.

The JSON format is often used for serializing and transmitting structured data over a network connection. It is used primarily to transmit data between a server and web application, serving as an alternative to XML.

Note that the information could come as a JSON Object or as a JSON Array. In this concrete case is a JSONArray.  To parse this formats in Java we have the package org.json.* and is easy to use. Let's see the simple code:


JSONArray jsonArray = new JSONArray(jsonRaw);
   int length = jsonArray.length();
   builder.append("Length: "+length+"\n");
   JSONObject jObject;
   for(int i=0; i < length;i++ ){
    jObject = jsonArray.getJSONObject(i);
    builder.append(jObject.getString("text")+"\n");
   }

In this case we are getting the String from the field text of each JSONObject in the array. There are lots of fields in each object.

Well that's a simple example of using REST and JSON in android. In further entries we'll see how to authenticate.

Tuesday, February 21, 2012

Android application components and developing our first app (II)

On the previous entry I explained android app activity concept. Now, on this entry I'm going to explain the other components of an application and we'll make our first android app.

 INTENTS
Intents are messages that are sent between activities or services. When they are received could launch processes. They have a little capacity of transport information (not so complex, basic data types, int, float... String). We can use them, for example, when we want to launch an activity from within another  activity and also if we want an activity to return something to the launcher activity once finished.

VIEWS
These are user interface graphic components, such as buttons, input text areas, lists... We can put them on the screen using a XML file or graphically using Eclipse.

SERVICES
Services are application components running in background, because of that they haven't got a graphic interface. For example music player is a service, and the music control application sends messages to start playing, stop or pause... Another example could be whatsapp or facebook services. They're running in the background standing by to receive messages to notify it. Keyboard has a service too.

CONTENT PROVIDERS
Content providers are used to store persistent data. There are some ones already defined and we can define new ones.

BROADCAST RECEIVERS
These components response to broadcast messages. These messages are usually sent by system, although they can be sent by applications as well. For example, when we use bluetooth, we need write an broadcast receiver to catch the messages sent by the system about the bluetooth state, if it's enabled or visible... (we'll see that in further entries). These receivers use intents to comunicate.

MANIFEST
 AndroidManifest.xml it's an important file within an application because in this file we configure the application. In this file we set the application activities, which one is the main activity (which will be launched first in application), which permissions will need, (sdcard access, internet, bluetooth... ), etc...

Here we finish the android application components description (very brief), and now, we are ready to start programming our first android application:


ANDROID HELLO WORLD APPLICATION 

You can find these instructions on the android developer website.

If we want to execute the application on an emulator, we have to create an AVD - Android Virtual Device. If you want to execute the application in your physical device (mobile or tablet), you can skip this step:

Create an AVD
From within Eclipse window->preferences->Android SDK and AVD manager: click Virtual Devices.
Click New, write a name and select the android platform it will work with. We have to keep in mind one thing, an 1.1 application will run in 1.5 platform, but not necessary will work backwards.

Create a project
We will need to create an android project in Eclipse. Type name, package, activity and platform...



Create android project button

Write name and select location

Select android platform

Write main activity name and select minimum platform version to run this application
Once created, enter to src and in HelloActivity.java add this:
import android.widget.TextView;
And modify the activity to look like this:

public class HelloActivity extends Activity {
        /** Called when the activity is first created. */
        @Override
        public void onCreate(Bundle savedInstanceState) {
                    super.onCreate(savedInstanceState);
                    TextView tv = new TextView(this);
                    tv.setText("HELLO COOERS, I AM ANDROID");
                    setContentView(tv);
       }
      }
 Within onCreate() method, which will be executed when activity is created, declare a TextView element, which will be used to show a text on the screen. In the following line we will set the text that will be shown, and after that, we show it on the screen using setContentView();

Save project and click Run->Run. This will launch the AVD (it will take some minutes) and then it will launch the application. If we want to run the app in a physical device, we have to plug the device to the computer before click Run. If your system recognise the device (as I explained near the end of first entry of this blog)  the application will automatically be installed and launched.


Well, we finally wrote code and have seen something on our device! But that was too easy. Don't worry because in following entries we will make things more interesting and complex.
See you soon!

Monday, February 20, 2012

Android application components and developing our first app (I)

Here we are again. In the previous entry of this blog we prepared the working environment to android app programming on Ubuntu. Therefore in this post we'll make our first android application using this environment. But, before we start to program, we should know about how android apps work.

BASIC ANDROID APP COMPONENTS


These are Activities, Intents, Views, Services, Content Providers, Broadcast Receivers and finally the Manifest. In the following paragraphs I will briefly describe each one to start programming as soon as possible:

ACTIVITIES

This is the main component of an android app. The main process is usually done here, or, at least, it starts from here. We could say an activity is like  a screen on our application, moreover we can only have one active activity at the same time. So an android application usually consists of several loosely-related activities.
We could see that like a stack. Top activity would be the active one, and we only would see this one. If we push another activity , this will be on top so this will be the active one. From this activity we can return to the previous one taking it out of the stack.

Stack



I told you application activities are loosely-related, because it was designed in that way, to avoid coupling and increase cohesion between application modules, and later we'll see that complex information sharing between activities is not easy.

Activities have a well-defined life cycle starting when activity is created (either by system call or by another activity call into the same application) until it's stopped or removed.

Activity life cycle

As we can see in this diagram, an activity goes trough several states during its life. You must know that when we stop an activity, android system do not destroy it immediately, but stops it, saving its resources in case it has to restart it. System will destroy the activity when deemed appropriate, either by memory requirement or by time running. So when you close an application in your device, doesn’t mean that this application is no longer in the memory.

Each time an activity changes state, it calls a method. You can see these methods on the diagram, onCreate(), onStart()...

So, when we will programming our activities, we'll be able to execute instructions that we need into each one of these methods. Therefore, looking at this diagram, we can see that, when we launch an activity (if it was not already in memory), method onCreate() will be automatically called, and after that,  onStart() method will be called, and then onResume() will be called...
When we leave an application or when activity goes to background, onPause() method will be called, and after that onStop() method will be called. Method onDestroy() will be called when the activity is finishing or being removed by the system, as I told, either by resource requirement or something similar.

If we pay attention to the diagram, we'll see that just before execute the main code in the activity, the system always will call onResume() method, and when we leave the activity onPause() always will be called. Therefore this two plus onCreate() will be the three most commonly used methods, although we don't have to forget the other ones.

To finish with this, I must say if we want to finish an activity by code, we can call the finish() method.

On the next entry I'll explain the rest of the application components and we'll make our first app.


Thursday, February 16, 2012

Android Development Environment on Ubuntu

First things first. To app programming in Android we need an working environment. There are many possibilities to configure this environment but in this entry I'm going to explain the one that I use.

Operating System:

Ubuntu 10.10 Maverick Meerkat
Programming Environment: Eclipse Indigo + ADT Plug-In
Latest Version Android SDK

I must say that there are new available updates of this OS, but I decided to use 10.10 because  Unity desktop (or Gnome Shell) are too slow, so working with them could become a nightmare.


First: Prepare the OS

You need to install the SUN ORACLE JDK.
  1. Download JDK from ORACLE download page.
  2. Unzip the packet: #tar -xvzf jdk7u2.tar.g
  3. Move created folder to /usr/local. You can also take advantage in this point to shortening the name, for example jdk7.2
  4. Now, you can tell the OS that uses this JDK with the following comands:
  5. #update-alternatives --install
    "/usr/bin/java" "java"
    "/usr/local/jdk7.2/bin/java" 1
  6. #update-alternatives --set java
    /usr/local/jdk1.7/bin/java
  7. Then you'll need to create the JAVA_HOME environment variable and update the PATH. To do this you can edit /etc/profile and add:
  8. export JAVA_HOME=/usr/local/jdk7.2
  9. export PATH=$JAVA_HOME/bin:$PATH
  10. Execute #source /etc/profile to load the environment variable
  11. Now JDK is installed. To check it you can try #java -version and the system should show infromation of the instaled version of Java.
This first part has not been too much complicated and the upcoming ones will be even more simple.

ECLIPSE AND ANDROID SDK INSTALLATION
 
Once JDK is installed we can move to the next point. Installing Eclipse programmer framework. At the moment I'm writing, latest version of this framework is Indigo. We can download it from the official site, getting the eclipse-java-indigo-SR1-linux-gtk.tar.gz file. Unzip this file in our personal folder (for example).
Once unziped you can go to the Ubuntu Menu,  System->Preferences->Main Menu. Here you can add new element to the programming menu and select the icon you will find into the unziped Eclipse folder.
The Android Developer page recommends to modify eclipse.ini to set the configuration like this:


-XX:MaxPermSize=256m
-Xms128m
-Xmx512m

It refers to the amount of memory to use by the Java Virtual Machine.

Now we must download the Android SDK. This contains libraries and utilities to connect the devices  to the computer. Unzip it and that's time to install ADT plug-in for Eclipse. This plug-in allow the communication between Eclipse and Android SDK. To install it you can go to Help->Install new software, in the Eclipse Menu. In the appearing dialog you must type the following direction:


https://dl-ssl.google.com/android/eclipse/


Typing address in ADT plug-in installation.




Once installation is done, you have to restart Eclipse and then you must configure ADT plug-in to link the SDK Android folder you unziped in the previous step (go to Window->Preferences->Android). With this plug-in you can download all Android Versions to develop. The majority of android devices uses version 2.2.1 or later. You must know that 3.x versions are only for tablets devices, and version 4.x are for both tablets and mobile devices, but, for the time being, it works only on the brand new Samsung Galaxy Nexus.

It seems that our development environment begins to be valid, but we still have one small thing to do: we need our system detects our device to be able to install apps and debbug it from Eclipse.

In Windows we have only to install drivers, but in Linux it's different. First we have to plug device to computer using USB.


MAKE UBUNTU DETECT ANDROID DEVICE TO DEVELOPMENT

First of all, we need to know device Vendor Id: We must use lsusb command and we'll see something like this, depending on the device brand:


Bus 002 Device 005: ID 18d1:4e22 Google Inc.

We have to look at first 4 numbers of ID.
Then, we should go to /etc/udev/rules.d and we'll see what are the names of .rules files (they should begin with a number, like 70 in my case).
In this case we would create a file named 70-android.rules writing on it the following:

SUBSYSTEMS=="usb", SYSFS{idVendor}=="xxxx", MODE="0666"

where xxxx would be the first 4 numbers of ID, that is 18d1 in my particular case.
Be careful with double quotes, because if there aren't appropiate it won't work. o be sure, the better is to write yourself, don't copy-paste.

Now you must unplug device and go to platform-tools folder into Android SDK unziped folder. There must be an executable named adb. From there you can execute the folowing commands:
sudo restart udev
./adb kill-server
./adb
start-server
./adb devices
Where we should see :


List of devices attached
34346DD882B200EC
device

If there are question marks means it has not worked.


note 1:(adb is located in
androidSDK/platform-tools
if we want to use adb like a regular command we must insert it in the PATH:


export
PATH=${PATH}:/home/TU_USUARIO/android-sdk/platform-tools
export
PATH=${PATH}:/home/TU_USUARIO/android-sdk/tools


and then we will be able to use adb much more comfortably
)



note 2: If any time trying to install an app to device from Eclipse you have the following error:


Unable to open sync
connection!

You can take two ways:
  1. restart device
  2. check out debugging mode and check in then
Obviously second way is faster.

Well, following these simple instructions taken mainly from the android developer website, you can get your Ubuntu ready to start developing android applications in a comfortable way. In this website you can find guides and samples to start, and in this blog we will start developing on following entries. See you soon!






Hello

This blog has been created to provide information I have been taken about android applications development. The blog will be focused on graphic applications (games) so it will include Open GL ES concepts, but all from the beggining.