This site has been archived and you can no longer log in or post new messages. For up-to-date community resources please visit ezplatform.com

eZ Community » Learn » eZ Publish » Building native mobile applications...

Building native mobile applications with the eZ Publish REST API

Thursday 13 October 2011 4:21:48 pm

  • Currently 4 out of 5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Android application, continued

Now we are going to fetch some data using the eZ Publish REST API. To help with this, we will use the “AsyncTask” class, which provides a simple, convenient mechanism for moving time-consuming operations into a background thread, and provides event handlers to communicate the progress and results of that thread.

However, before we will start implementing “AsyncTask”, we need to allow our application to access the Internet connection. Open “AndroidManifest.xml” and add the following line before the closing </manifest> tag:

<uses-permission android:name="android.permission.INTERNET"/>
 

To create a new asynchronous task, we need to extend “AsyncTask”, but first we need to add a new Java class to our project. Select “New -> Class” from the “File” menu in the “src/com.ez” package. In the resulting window, enter the name “NodeListAsyncTask”, then click the “Finish” button. Enter the following as the code for the class:

public class NodeListAsyncTask extends AsyncTask<String, Void, Node[]> {
    private ProgressDialog progressDialog;
    private Context context;

    public NodeListAsyncTask(Context context) {
        this.context = context;
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        
        // [... Display progress bar, or other UI element ...]
    }

    @Override
    protected Node[] doInBackground(String... requestURL) {
        Node[] nodes = null;

        // [... Perform background processing task ...]

        return nodes;
    }

    @Override
    protected void onPostExecute(Node[] result) {
        super.onPostExecute(result);

        // [... Report results via UI update, Dialog or notification ...]
    }
}
 

An “AsyncTask” object takes a string as an input parameter: this will be the eZ Publish REST resource URL. For the other parameters, we will use “Void” for progress reporting and a node array for the execution result. In the constructor, we will pass the context in which the asynchronous task was performed.

In the “onPreExecute()” method, we will display a progress bar to the user:

@Override
protected void onPreExecute() {
    super.onPreExecute();

    this.progressDialog = ProgressDialog.show(this.context, "Please wait ...",
            "Acquiring data", true);
}
 

In the “doInBackground()” method, we will implement the actual connection to the eZ Publish REST web service and parse the JSON response, translating it into business objects:

@Override
protected Node[] doInBackground(String... requestURL) {
    
    Node[] nodes = null;
    String requestString = requestURL[0];
    
    try {
        DefaultHttpClient httpClient = new DefaultHttpClient();
        HttpGet request = new HttpGet(requestString);
        HttpResponse response = httpClient.execute(request);

        String result = EntityUtils.toString(response.getEntity());
        JSONObject root = new JSONObject(result);
        JSONArray childrenNodes = root.getJSONArray("childrenNodes");

        nodes = new Node[childrenNodes.length()];
        
        for (int i = 0; i < childrenNodes.length(); i++) {
            JSONObject childNode = childrenNodes.getJSONObject(i);
            
            Node node = new Node();
            node.setId(childNode.getInt("nodeId"));
            node.setName(childNode.getString("objectName"));
            nodes[i] = node;
        }
        
    } catch(Exception e) {
        e.printStackTrace();
    }

    return nodes;
}
 

In the “onPostExecute()” method, we will dismiss the progress dialog and notify the view that data processing is finished:

@Override
protected void onPostExecute(Node[] result) {
    super.onPostExecute(result);

    this.progressDialog.dismiss();

    ((JSONListActivity)this.context).onNodeListResult(result);
}
 

Now that data access is implemented, we need to update the view upon a finished asynchronous task by using the following methods in “JSONListActivity.java”:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    new NodeListAsyncTask(this).execute("http://www.example.com/api/ezp/content/node/2/list");
}

public void onNodeListResult(Node[] nodes) {
    this.setListAdapter(new ArrayAdapter<Node>(this, android.R.layout.simple_list_item_1, nodes));
}
 

Notice that we are executing “NodeListAsyncTask” by creating a new instance of it with the context parameter, and calling its “execute()” method with the eZ Publish REST URI resource (which should return information about the children of the node with an ID of 2).

Build and run the application. You should see the following result:

Android Reader

 

Populating the detail view

Next, we are going to implement the full view of a page, shown when users tap a row in the table list view. In order to do so, we need to create a new activity class. Select “New -> Class” from the “File” menu in the “src/com.ez” package. In the resulting window, enter the name “DetailActivity” and the superclass “android.app.Activity”. Then, click the “Finish” button.

Android Detail view creation

 

Once a new activity class is created, we need to register it in the application. In order to do so, open “AndroidManifest.xml” and paste the following code before the </application> closing tag:

<activity android:name="DetailActivity"
          android:screenOrientation="portrait"/>
 

Next, we need to create a layout file for “DetailActivity”. In “res/layout”, create a “detail.xml” file with the following content:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <WebView 
        android:id="@+id/webview"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
    />
</LinearLayout>
 

Then, we need to implement the “onCreate” method, which is called when the activity is first created. In “DetailActivity.java”, add the following:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.detail);
}
 

Now that we have implemented the base code for “DetailActivity”, we can load it whenever the user taps on a table list view row. Implement the following method in “JSONListActivity.java”:

@Override
public void onListItemClick(ListView l, View v, int position, long id) {
    super.onListItemClick(l, v, position, id);
    
    Intent detailIntent = new Intent(v.getContext(), DetailActivity.class);
    detailIntent.putExtra("Node", (Node)this.getListAdapter().getItem(position));
    startActivityForResult(detailIntent, 0);
}
 

Build and run application to verify that there are no code errors. The detail view does nothing at the moment. We need to implement data access similar to what we did for the table list view by using “AsyncTask”. Select “New -> Class” from the “File” menu in the “src/com.ez” package. In the resulting window, enter the name “NodeAsyncTask”, and the superclass “android.os.AsyncTask<String, Void, String>, then click the “Finish” button. Paste the following code:

package com.ez;

import android.os.AsyncTask;

public class NodeAsyncTask extends AsyncTask<String, Void, String> {

}
 

We then need to implement three familiar methods: “onPreExecute()” (which shows a progress dialog), “doInBackground()” (which grabs the data), and “onPostExecute()” (which clears the progress dialog and passes the data result to “DetailActivity”).

public class NodeAsyncTask extends AsyncTask<String, Void, String> {
    private ProgressDialog progressDialog;
    private Context context;

    public NodeAsyncTask(Context context) {
        this.context = context;
    }
    
    @Override
    protected void onPreExecute() {
        super.onPreExecute();

        this.progressDialog = ProgressDialog.show(this.context, "Please wait ...",
                "Acquiring data", true);
    }
    
    @Override
    protected String doInBackground(String... requestURL) {
        
        String renderedOutput = null;
        String requestString = requestURL[0];
        
        try {
            DefaultHttpClient httpClient = new DefaultHttpClient();
            HttpGet request = new HttpGet(requestString);
            HttpResponse response = httpClient.execute(request);

            String result = EntityUtils.toString(response.getEntity());
            JSONObject root = new JSONObject(result);
            
            renderedOutput = root.getString("renderedOutput");
        } catch(Exception e) {
            e.printStackTrace();
        }

        return renderedOutput;
    }

    @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);

        this.progressDialog.dismiss();

        ((DetailActivity)this.context).onNodeResult(result);
    }
}
 

Now that we have implemented “AsyncTask” for getting detailed node data, it is time to use it. Add the following code into “DetailActivity.java”:

public class DetailActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.detail);
        
        Node node = (Node)getIntent().getExtras().get("Node");
        
        new NodeAsyncTask(this).execute(String.format("http://www.example.com/api/ezp/content/node/%d?OutputFormat=xhtml", node.getId()));
    }
    
    public void onNodeResult(String result) {   
        WebView webview = (WebView) findViewById(R.id.webview);
        webview.loadData(result, "text/html", "utf-8");
    }
}
 

Build and run the application. Test the detail view by tapping on a row in the table list view. We should see the following output.

Android - detail view

 
36 542 Users on board!

Tutorial menu

Printable

Printer Friendly version of the full article on one page with plain styles

Author(s)

Proudly Developed with from