Android Phone-Top Programming, Part 2

Creating a simple application debug tool out of an App Widget

Debug widget for Android

Most software programmers my age began their career with a program that looks similar to this:

10 Print "Frank"
20 Goto 10

Unless you and I share a first name, your program probably looked a little different.

And for those not old enough to have heard the term “supply-side” or “trickle-down”, perhaps your first program looked more like this:

public class MyClass
    public static void main(String[] args)
        System.out.println("Your name");

Either way, we have been “printing” stuff forever.

When it comes to trouble-shooting an application printing things to the screen, or to a file, is not as full-featured as attaching a debugger to a running device, but there is a time and place for printing a simple message to the screen.

When debugging an application during development writing to the LogCat is often your best bet — and every Android programmer should make sure they are comfortable with the LogCat tool. But getting access to a small piece of information from a user who has purchased your application can be a bit trickier because they are not likely to have the Android development tools installed on their computer — if indeed they have one!

So let’s move forward on the premise that it would be useful to see some small pieces of information at runtime.

We can add this functionality to many Android applications, provided they have a user interface. But what if your application is a Service or a Content Provider only? Or what if a hard-to-find problem occurs when you are sleeping during an over-night update process? Or something happens on the phone while you are in the middle of a 200 foot plunge from a bridge with a bungee-cord? You get the idea.

To meet this basic objective of seeing what is happening inside of one of our applications, let’s add some functionality to our AppWidget.

In a previous post we reviewed the basics of an AppWidget. In this installment we will add some incremental functionality by building an AppWidget that can receive messages from other applications and display the message to the user.

Application Description

The AppWidget we are constructing has the capability of displaying two important pieces of information:

  • msg – A textual message of arbitrary composition.
  • sender – Which application or routine sent the message.

The ability to display a “sender” helps to distinguish the source of the message. The application may receive a message either from multiple, distinct applications and/or from distinct methods within a single application. The “sender” field is logically equivalent to the “tag” attribute found in the android.util.Log methods.

Because this widget lets us “see” into an application — sort of — it is named “LM App Eyes”.

For now, the AppWidget only displays the most recent message received. In a future post we will expand this further to show a full history of debugging messages received.

Let’s have a look at the code.

The AppWidget code

The code for this AppWidget looks very similar to our previous example, however we have made some refinements to accommodate the specific functionality we are looking for.

The class has two new variables, one to hold the “sender” and one to hold the “message”:

	private String lastMessage = "Waiting on Message";
	private String lastSender = "";

In the onReceive() method we are now on the look-out for a particular type of Intent, namely an Intent with an action value of “com.msi.linuxmagazine.TRACEME”. If the application encounters this Intent, we need to do some additional processing.

		if (intent.getAction().equals("com.msi.linuxmagazine.TRACEME")) {
			lastMessage = intent.getStringExtra("msg");
			lastSender = intent.getStringExtra("sender");
			Log.i(tag,lastMessage + " from " + lastSender);
			AppWidgetManager appManager = AppWidgetManager.getInstance(context);
			int [] ids = appManager.getAppWidgetIds(new ComponentName(context,LMAppEyes.class));

In this code snippet, taken from the onReceive() method, we are extracting two pieces of information which were supplied as “extras” in the Intent. We’ll examine how the Intent is constructed later in this article.

Once we have extracted the relevant data elements, we want the AppWidget instance(s) to update. To accomplish this we get a reference to the AppWidgetManager and obtain a list of the instantiated widgets. From here a call to the onUpdate() method causes the widget to update and show our most recent message.

	public void onUpdate(Context context,AppWidgetManager appWidgetManager,int[] appWidgetIds ) {

		super.onUpdate(context, appWidgetManager, appWidgetIds);
		int count = appWidgetIds.length;
		Log.i(tag,"onUpdate::" + count);
		// we may have multiple instances of this widget ... make sure we hit each one ...
		for (int i=0;i<count;i++) {
			Log.i(tag,"Updating text view ....");
			RemoteViews views = new RemoteViews(context.getPackageName(),R.layout.main);
			if (lastSender.equals(""))
				views.setTextViewText(R.id.senderName, lastSender);
				views.setTextViewText(R.id.senderName, lastSender + " says:");
			views.setTextViewText(R.id.lastMessage, lastMessage);


The Tester code

In order to get a message to our widget, we are going to employ the sendBroadcast() method from another application. For this purpose we’ve got a simple application named “GenericTester” — here is the code:

package com.msi.linuxmagazine.gt;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.Button;

public class GenericTester extends Activity {

	private int counter = 0;
    /** Called when the activity is first created. */
    public void onCreate(Bundle savedInstanceState) {

        final Button btnSendMessage = (Button) findViewById(R.id.SendMessage);
        final EditText etInputText = (EditText) findViewById(R.id.inputText);

        // default some text here
        etInputText.setText("some message");

        btnSendMessage.setOnClickListener(new View.OnClickListener(){
        	public void onClick(View v){
        		Log.i(GenericTester.class.getName(),"Button Clicked! " + counter);
        		try {
        		    // setup the Intent
        			Intent traceIntent = new Intent();
        			// store the message and the sender
        			traceIntent.putExtra("msg", etInputText.getText().toString());
        			// shoot this off asynchronously
        		} catch (Exception e) {
        			Log.e(GenericTester.class.getName(),"Error occured [" + e.getMessage() + "]");

In order for the AppWidget to receive this broadcast we must setup an Intent Filter in the AppWidget’s AndroidManifest.xml file:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
<application android:icon="@drawable/icon" android:label="LM App Eyes">
	<receiver android:name=".LMAppEyes">
			<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
			<action android:name="com.msi.linuxmagazine.TRACEME" />

		<meta-data android:name="android.appwidget.provider"
			android:resource="@xml/lmappeyes" />


To test the application, we first need an instance of the AppWidget on the home screen of the phone.

Insert Widget to Home Screen
Insert Widget to Home Screen

Select the LM App Eyes Widget

Choose LM App Eyes
Choose LM App Eyes

When the widget first loads, it is in the “waiting” stage — i.e., no messages have been received just yet.

Waiting for a message
Waiting for a message

Now, let’s send some data via the testing application.

Simulate a message
Simulate a message

We can see that the GenericTester application has sent a message!

Display a message
Display a message

Further thoughts

At this point, our AppWidget is functional. However, there are a couple of features that would be nice to add:

  • This code updates any and all instances of the widget with the same content. It would be nice to have the choice to create multiple instances of the widget, each “tuned” into a specific sender or source.
  • The widget displays only the most recent message, meaning that we might have missed one or more messages depending on when we most recently observed the widget.

In future articles we will add these pieces of functionality. For now, you can download the code from the Linux Magazine Google Code hosting site.

Comments on "Android Phone-Top Programming, Part 2"

other miscellaneous insurance car driver party under free auto insurance quotes free insurance where cheap car insurance many people always insurance auto family protection

dui unless car insurance companies trains buses auto insurance cheap getting miles per car insurance quotes companies continues numerous car insurance quotes quite most cases car insurance online shopping skilled tradesmen cheapest car insurance paper trail total amount car insurance applying makes insurance auto auto

passenger car insurance quotes deductible insurance providers car insurance quotes comprehensive coverage better chance automobile insurance other unfortunate cheap auto insurance worth asking best way car insurance leading familiar insurance insurance auto great system offer auto insurance quotes kentucky collision coverage car insurance rate policy reads

certain minimum insurance quotes auto financial loss few states online car insurance quotes quotes risks policy free car insurance quotes about various register car insurance age groups many cases cheapest car insurance many factors circumstances auto insurance quote old anti-theft feasible budget-wise car insurance quotes related accidents cheap auto insurance car auto

car taken cheap auto insurance leeway within best cheap insurance quotes car car claim online car insurance quotes insurance company car insurance quotes most insurers comprehensive car insurance quotes coverage while typically more cheapest car insurance miles rates free auto insurance quotes vandalism storm

other driver car insurance auto assurance more thing automobile insurance quotes information considerable shifts free car insurance quotes useful hours where worker insurance auto teenager

consumer might cheap car insurance birth certificate make each insurance quotes auto here should car insurance rates same policy while car insurance quotes statistically women premiums car insurance rates good enclosed providers offer cheapest car insurance need insurance look cheap auto insurance commuting give auto insurance quote company websites

Leave a Reply