Monday 23 June 2014

Ordered Broadcasts

There are two types of broadcasts in Android: normal and ordered. The following table shows the main differences:


Normal
Ordered
Way of delivery
Normal broadcasts are delivered to the available receivers asynchronously, in an unspecified order
Ordered broadcasts are delivered to the available receivers one at a time, in a specified order (the order depends on the android:priority attribute of the different receivers in the AndroidManifest file)
Feedback
With normal broadcasts no feedback can be sent to the broadcaster
With ordered broadcasts the receiver can send information to the broadcaster (using the methods abortBroadcast(), seResultCode(), setResultData()


Tip: in a receiver (handling ordered broadcasts) you can call the method abortBroadcast() to make sure that the broadcast is not sent to other receivers. If you combine this method with a high value for the android:priority attribute, you can make sure that your receiver is the only one to handle that broadcast (SMS apps can use this technique).

BroadcastReceiver in Android

BroadcastReceiver

Let’s see how a BroadcastReceiver can handle ordered broadcasts (se the comments in the code for more information):
public class MyReceiver extends BroadcastReceiver {
    [...]
    public void onReceive(Context context, Intent intent) {
        //is this an ordered broadcast or not?
        if(isOrderedBroadcast() {
            //here you can handle the broadcast    
            [...]

            //here you can send information back to the broadcaster
            setResultCode(Activity.RESULT_OK);
            setResultData(“here you can pass a String”);

            //you can also create complex data to send to the broadcaster
            Bundle myBundle = getResultExtras(true);
            myBundle.put [...] //code omitted for brevity
        }
    }
}


Broadcaster

Sending an ordered broadcast is quite simple. Let’s look at the code:
Intent int = new Intent(YOUR_FILTER);
sendOrderedBroadcast(int, responseReceiver, null, RESULT_OK, null, null);
As you can see you just have to create an Intent with the filter registered for the BroadcastReceiver MyReceiver and call the method sendOrderedBroadcast. This method takes a BroadcastReceiver (responseReceiver) as a parameter: this is the receiver that will receive the information sent back by the BroadcastReceiver MyReceiver.
So you finally have to register the BroadcastReceiver responseReceiver (to handle the results) in the following way:
BroadcastReceiver responseReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        //here you can retrieve the results sent by MyReceiver
        String str = getResultData();

        //here you can retrieve the complex data sent by MyReceiver
        Bundle myBundle = getResultExtras(false);
        if(myBundle != null) {
            //here you can retrieve the data using myBundle.get... methods
        }
    }
}

Friday 13 June 2014

Creating a pie chart with aChart Engine

In many Android apps you may need to show data in graphical format (pie charts, bar charts, time charts, etc.). To do this you can write the code from scratch, or use one of the many third-party libraries available. One of the most used is certainly aChart Engine, and there are several good reasons for that:
  1. it is leight;
  2. it is free;
  3. it is relatively complete.

In this brief tutorial I will explain the most important features you must know to create a pie chart using aChart Engine.



Download and install the library

First of all you have to download the library (version 1.1.0) and set up your Eclipse project to use it. The steps are the following:
  1. donwload the library (jar file, version 1.1.0) from this link. You can find the complete documentation of the package here;
  2. open Eclipse; right click on the main project folder; select "Build Path" and "Configure Build Path..."; select "Libraries" tab; click on "Add external Jars..." and select the library Jar file you have downloaded.
Now your Eclipse project is ready to use the library. Of course, if you want to use the different classes, you first have to import them in your Activity (import org.achartengine.model.CategorySeries ... etc.). 

Source data

Let’s suppose we want to create a pie chart showing the distribution of the different Android versions, using the following data:
Kit Kat – 7.8%
Jelly Bean – 33%
Ice Cream Sandwich – 25%
Honeycomb – 17%
Gingerbread – 11%
Older – 6.2%

Each slice of the pie chart is represented by a different color.
The source data in Java is represented by three arrays, each with six elements:

String[] labels = new String[] {“Kit Kat”, “Jelly Bean”, “Ice Cream Sandwich”, “Honeycomb”, “Gingerbread”, “Older”};
double[] values = {7.8, 33, 25, 17, 11, 6.2};
int[] colors = {Color.RED, Color.BLUE, Color.GREEN, Color.MAGENTA, Color.YELLOW, Color.GRAY};

CategorySeries

The class CategorySeries of aChart Engine (org.achartengine.model.CategorySeries) is used to represent a series for the category charts like the pie ones.
We create an instance of this class and populate it with the previously showed source data (labels and values):

CategorySeries categorySeries = new CategorySeries(“Android versions”);
for(int i=0; i<labels.length; i++) {
    categorySeries.add(labels[i], values[i]);
}

DefaultRenderer

The class DefaultRenderer (org.achartengine.renderer.DefaultRenderer) is an abstract renderer used to format the charts.
We can create an instance of this class and specify how we want our pie chart to be rendered:

DefaultRenderer defaultRenderer = new DefaultRenderer();
defaultRenderer.setChartTitle(“Android versions”);
defaultRenderer.setChartTitleTextSize(30);
defaultRenderer.setZoomButtonsVisible(false);
...
NB: It is important to set the zoom buttons visibility to false, otherwise you may get a NullPointerException in the onDraw() method of the class GraphicalView (as far as I know, this should be a bug in the library).
The are of course many other formattings you can control using a DefaultRenderer: you can read the official documentation for more information.

To control the rendering of each slice of the pie chart (color, showing or not showing values, etc.) you can use the SimpleSeriesRenderer class (org.achartengine.renderer.SimpleSeriesRenderer): you just have to create an instance of this class for each slice, set the relevant data and add it to the previously defined DefaultRenderer:

for(int i=0; i<labels.length; i++) {
    SimpleSeriesRenderer simpleSeriesRenderer = new SimpleSeriesRenderer();
    simpleSeriesRenderer.setColor(colors[i]);
    simpleSeriesRenderer.setDisplayChartValues(true);
    ...
    defaultRenderer.addSeriesRenderer(simpleSeriesRenderer);
}

Starting a new Activity

To show our pie chart we first have to retrieve an Intent, populated with the relevant data, using the ChartFactory class:

Intent intPiechart = ChartFactory.getPieChartIntent(context, categorySeries, defaultRenderer, “Android versions”);
startActivity(intPieChart);

The new Activity must be declared in the AndroidManifest.xml file as well:

<activity android:name=”org.achartengine.GraphicalActivity”/>