Publishing messages from Android in the background

With this recipe, we are going to complete the project we began in the previous recipe; we will implement an Android app that publishes the current device's position to RabbitMQ. This example is simpler than the previous one, as we are not going to plot the positions on a map, but we still need the Google Play services since we have decided to make use of their location service; it provides a useful abstraction for the available location sensors available on the device, letting the application be compatible with a wide spectrum of Android devices.

Getting ready…

To put to work this recipe, we need:

How to do it…

  1. From the Android SDK Manager, install Google Play services, as already seen in the previous recipe.
  2. Create a new Android application. Following the wizard, the minimum required SDK must be set to API11. Create a Blank Activity.
  3. Carefully follow the instructions provided by Google to set up the Google Play services (http://developer.android.com/google/play-services/setup.html).
  4. Copy the RabbitMQ library files (commons-cli-1.1.jar, commons-io-1.2.jar, and rabbitmq-client.jar) in the libs directory of the project.
  5. In place of the Hello world! TextView, created by the Eclipse wizard, insert a switch widget that we name followmeSwitch. You can edit the corresponding XML layout file activity_main.xml and insert the following:
    <Switch
    android:id="@+id/followmeSwitch"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginLeft="28dp"
    android:text="@string/followme" />
  6. Create the SenderService class that extends IntentService.
  7. Set the action of the switch in MainActivity.java:
    final Switch fms = (Switch)findViewById(R.id.followmeSwitch);
    fms.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
    @Override
    public void onCheckedChanged(CompoundButtonbuttonView, booleanisChecked) {
    if (isChecked) {
    serviceIntent = new Intent(MainActivity.this, 
    SenderService.class);
    startService(serviceIntent);
    } else {
    stopService(serviceIntent);
    }
    }
    });

How it works…

In this recipe, we have approached another typical pattern that we can meet by mixing RabbitMQ and Android technologies: publishing messages in the background, even when the user interface is not visible on the Android device.

We have first created a standard Android application with just a switch; on turning it on, we start delivering messages to the RabbitMQ broker. When turned off, we stop it.

So we have bound the actions of followmeSwitch to the SenderService (step 7). It's important to remember that when we start a background job with an Android service, the background events are still executed by the application's main thread, and we need to apply the same responsiveness guidelines that we follow when we design Android GUIs.

However, in our example, we have decided to make use of the IntentService helper class that starts a background thread that can run indefinitely.

It's in this thread that we connect to the broker and periodically send RabbitMQ messages reporting the current position of the device acquired by calling locationClient.getLastLocation() (see the source file with the class referred by the step 6).

Note

In this example, we have used the Android standard serializer android.util.JsonWriter in place of the RabbitMQ JSONWriter that we have seen previously. In fact, this one doesn't work on Android because Dalvik includes only a subset of the Java beans, missing the ones related to reflection.

As soon as the user turns off the switch, we just exit this thread.

By running this application on one device, and one of the previous recipes on another, we are able to communicate our georeferenced position by using RabbitMQ messages.

There's more…

The Google localization client library allows raising events on location changes, so this should be the preferred method to send coordinates. This approach can be optimized to conserve battery usage on the device, but we have avoided it for the sake of simplicity.

However, the application is already fully functional; you can run many different devices as consumers—and all of them will update the position synchronously, as we publish the messages to a fanout exchange.

You can even run many producers concurrently, but the current implementation will just mix their data together; to draw many different traces from different devices, it comes handy to replace the fanout exchange with a topic exchange and give a different routing key to each producer.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset