Archive

Archive for January, 2012

Creating A Simple RSS Application in Android

January 21, 2012 103 comments

In this tutorial we will build a simple rss application.

Requirements are:
1) parse an rss feed and display the headlines in a ListView
2) when the user clicks on a headline, open the Android browser and redirect to corresponding web page.


Note: this tutorial is outdated. I would suggest you follow the new tutorial. The new tutorial is more extended, but it addresses few issues present in this example. On the other hand, if you are not looking for a very detailed tutorial and are interested only in XML parsing part, feel free to browse this example.

We will parse the PCWorld‘s rss looking for the latest news: http://feeds.pcworld.com/pcworld/latestnews

The final result will look like in the screenshot below:

android rss app

1. Create a new project in Eclipse:
Project: SimpleRssReader
Activity: SimpleRssReaderActivity

2. Add required permissions to AndroidManifest file.
The application will make use of Internet, so this should be specified in the AndroidManifest file, otherwise an exception will be thrown. Just after the <application> tag, (as a child of <manifest> tag), add the following line:

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

3. Open the main.xml layout file, delete the already existing TextView control, and add instead a ListView with the id “list”. This should should look like this:

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

<ListView
android:id="@+android:id/list"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
</ListView>

</LinearLayout>

4. Lets create the skeleton of our main activity.
Open the SimpleRSSReaderActivity and make it extend ListActivity, instead of Activity as it  comes by default. We need this in order to display the headlines in the ListView by binding to an array which will hold our data, using the list view adapter.
Add 2 instance variables: “headlines” and “links” of type List.

It should look like this:

public class SimpleRSSReaderActivity extends ListActivity {

	List headlines;
	List links;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

	}
}

5. In the onCreate() method, just after the setContentView(….) , add following lines:

// Initializing instance variables
headlines = new ArrayList();
links = new ArrayList();

try {
	URL url = new URL("http://feeds.pcworld.com/pcworld/latestnews");

	XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
	factory.setNamespaceAware(false);
	XmlPullParser xpp = factory.newPullParser();

        // We will get the XML from an input stream
	xpp.setInput(getInputStream(url), "UTF_8");

        /* We will parse the XML content looking for the "<title>" tag which appears inside the "<item>" tag.
         * However, we should take in consideration that the rss feed name also is enclosed in a "<title>" tag.
         * As we know, every feed begins with these lines: "<channel><title>Feed_Name</title>...."
         * so we should skip the "<title>" tag which is a child of "<channel>" tag,
         * and take in consideration only "<title>" tag which is a child of "<item>"
         *
         * In order to achieve this, we will make use of a boolean variable.
         */
	boolean insideItem = false;

        // Returns the type of current event: START_TAG, END_TAG, etc..
	int eventType = xpp.getEventType();
	while (eventType != XmlPullParser.END_DOCUMENT) {
		if (eventType == XmlPullParser.START_TAG) {

			if (xpp.getName().equalsIgnoreCase("item")) {
				insideItem = true;
			} else if (xpp.getName().equalsIgnoreCase("title")) {
				if (insideItem)
					headlines.add(xpp.nextText()); //extract the headline
			} else if (xpp.getName().equalsIgnoreCase("link")) {
				if (insideItem)
					links.add(xpp.nextText()); //extract the link of article
			}
		}else if(eventType==XmlPullParser.END_TAG && xpp.getName().equalsIgnoreCase("item")){
			insideItem=false;
		}

		eventType = xpp.next(); //move to next element
	}

} catch (MalformedURLException e) {
	e.printStackTrace();
} catch (XmlPullParserException e) {
	e.printStackTrace();
} catch (IOException e) {
	e.printStackTrace();
}

// Binding data
ArrayAdapter adapter = new ArrayAdapter(this,
		android.R.layout.simple_list_item_1, headlines);

setListAdapter(adapter);

6. In the onCreate() method we passed an input stream to setInput(): xpp.setInput(getInputStream(url), "UTF_8");
getInputStream() is not a standard Java method, so we should create it. This method should take as an argument the feed url, and return the input stream.


public InputStream getInputStream(URL url) {
   try {
       return url.openConnection().getInputStream();
   } catch (IOException e) {
       return null;
     }
}

7. Finnaly, we want when a title is clicked, the Android browser to be opened and display the corresponding article. This one is simple, we override the onListItemClick() method, get the position of article in the ListView, retrieve the coresponding link, and pass the url of that article to ACTION_VIEW intent which takes care further of displaying the web page.


@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
   Uri uri = Uri.parse(links.get(position));
   Intent intent = new Intent(Intent.ACTION_VIEW, uri);
   startActivity(intent);
}

By this time you should compile and run successfully the application.

Well, if everything went fine and you are done with the simple rss application, the next step to consider is how can you enhance the visual aspect of the application. Adding some style to the ListView, for example alternating between background colors, or displaying an icon next to each headline, can considerably increase the visual aspect, which will make your application look more appealing.
Take a look at this tutorial: Building a Custom Fancy ListView in Android, where I show in details how to achieve this.

This application, however, has one major drawback. Its drawback is that all the parsing and network access is done on the UI thread. As a result, you may notice that when starting the application, it “freezes” for a few seconds and then displays the headlines. To fix this issue, you should put all the parsing functionality in a background thread. In regards how to do that, you definitely should consider this post: Understanding AsyncTask – Once and Forever

Receiving a SMS in Android Emulator

January 20, 2012 3 comments

1. Start the Android Emulator

2. Open up the windows console by going to Start -> Run (or Windows + R shortcut) and type in “cmd” and press enter.

3. Type in “telnet” and press enter. This should open the Telnet Console.
(If you encounter this error: ‘telnet’ is not recognized as an internal or external command, operable program or batch file, open this link and scroll down to see how to fix it: http://androidresearch.wordpress.com/2012/01/18/how-to-simulate-an-incoming-call-in-android/)

4. Telnet Console being displayed, type in “o localhost 5554″. This will establish a connection with the emulator on port 5554 and open the Android Console. 5554 is the port number and you can see it on the title bar of the emulator window.

5. To send the sms, type in: “sms send 0789456 Hello World″.
As a result, a notification will notify you that a new sms has arrived.

6. Use “exit” to exit the Android Console, and “quit” to quit the Telnet client.

Android send sms

How to simulate an incoming call in Android

January 18, 2012 1 comment

1. Start the Android Emulator

2. Open up the windows console by going to Start -> Run (or Windows + R shortcut) and type in “cmd”. Press Enter. This should open the dos console.

3. Type in “telnet” and press enter. This should open the Telnet Console.
(At this stage you may experience some problems, the console may display the error: ‘telnet’ is not recognized as an internal or external command, operable program or batch file. If this is the case, scroll down to see how to fix it, then return and continue the process)

4. Telnet Console being displayed, type in “o localhost 5554″. This will establish a connection with the emulator on port 5554 and open the Android Console. 5554 is the port number and you can see it on the title bar of the emulator window.

5. To simulate the call, type in “gsm call 099062274″

6. To cancel the call, type “gsm cancel 099062274″

7. Use “exit” to exit the Android Console, and “quit” to quit the Telnet client.

That’s it!

android incoming call

*How to fix the: ‘telnet’ is not recognized as an internal or external command, operable program or batch file error.

When trying to invoke the telnet program you may experience the above error. The cause of this could be that the Telnet Client is turned off on your computer.

To turn it on, follow these steps:
1. Go to Control Panel

2. Click on Programs

3. Under Programs and Features section, click on Turn Windows features on or off. This should bring you the Windows Features pop-up.

4. Find the Telnet Client, select it, click OK.

Parsing XML with XmlPullParser

January 17, 2012 6 comments

XmlPullParser is an interface that provides parsing functionality. The below code is an example of XmlPullParser usage.

We will parse the Youtube feed that contains the most highly rated YouTube video, looking for “<title>” tag and extracting the text inside.

URL Feed: https://gdata.youtube.com/feeds/api/standardfeeds/top_rated


//We will put the data into a StringBuilder
StringBuilder builder=new StringBuilder();

URL url = new URL("https://gdata.youtube.com/feeds/api/standardfeeds/top_rated");

XmlPullParserFactory factory=XmlPullParserFactory.newInstance();
factory.setNamespaceAware(true);
XmlPullParser xpp=factory.newPullParser();

xpp.setInput(getInputStream(url), "UTF_8");

int eventType=xpp.getEventType();
while(eventType!=XmlPullParser.END_DOCUMENT){
  // Looking for a start tag
  if(eventType==XmlPullParser.START_TAG){
    //We look for "title" tag in XML response
    if(xpp.getName().equalsIgnoreCase("title")){
      //Once we found the "title" tag, add the text it contains to our builder
      builder.append(xpp.nextText()+"\n");
    }
  }

  eventType=xpp.next();
}

And here’s the implementation of getInputStream() method:

public InputStream getInputStream(URL url) {
  try {
    return url.openConnection().getInputStream();
  } catch (IOException e) {
    return null;
  }
}

Showing status bar notifications in Android

January 15, 2012 3 comments

A status bar notification adds an icon to the system’s status bar with an optional ticker-text message and a notification message in the notifications window. When the user selects the notification, usually an Activity is opened. The notification can be configured to alert the user with a sound, a vibration, and flashing lights on the device.

In the example below a notification is fired imediatly and when user clicks on it, the PostNotification activity opens.


@Override
public void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   setContentView(R.layout.main);

   // Get a reference to the NotificationManager
   NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

   // Instantiate the Notification with an icon, ticker text, and when to be displayed
   int icon = R.drawable.ic_launcher;
   CharSequence tickerText = "New notification";
   long when = System.currentTimeMillis(); //now
   Notification notification = new Notification(icon, tickerText, when);

   // Define the notification's message and PendingIntent
   Context context = getApplicationContext();
   CharSequence title = "Notification title";
   CharSequence text = "Notification description";
   // The activity PostNotification.class will be fired when notification will be opened.
   Intent notificationIntent = new Intent(this, PostNotification.class);
   PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);

   // Makes the notification disappear after clicked in the status bar
   notification.flags|=Notification.FLAG_AUTO_CANCEL;

   // When the notification will be fired, notify the user with default notification phone sound.
   notification.defaults|=Notification.DEFAULT_SOUND;

   notification.setLatestEventInfo(context, title, text, pendingIntent);

   // Pass the Notification object to NotificationManager
   notificationManager.notify(1, notification);
}

If you’d like to try the example above, create a new Activity called: PostNotification, create a new layout file, say postnotification.xml and add in the PostNotification activity:


setContentView(R.layout.postnotification);

Ultimately, do not forget to register the PostNotification activity in the AndroidManifest file:


<activity android:name=".PostNotification"></activity>

Keytool throws: The program can’t start because jli.dll is missing from your computer

January 11, 2012 1 comment

In order to develop an application that uses the Google Maps, you should obtain first a Maps API key registered via the MD5 fingerprint of the debug certificate. To find the MD5 fingerprint of your debug certificate you should use the keytool to generate it.

When using the keytool you may encounter following error:

android keytool error jli

The Keytool as well as jli.dll files are part of Java SDK /bin directory, and when you generate the MD5 code, both Keytool and jli.dll files should be in the same directory, if they are not in the same directory, then the above error is thrown.

The simplest way to generate the MD5 fingerprint is to:

1. Copy both keytool and jli.dll into debug keystore location:

  • Windows Vista: C:\Users\<user>\.android\debug.keystore
  • Windows XP: C:\Documents and Settings\<user>\.android\debug.keystore
  • OS X and Linux: ~/.android/debug.keystore

2. Navigate with the command prompt to debug keystore location and run the following command to:

a)  generate a Debug certificate:


keytool -list -alias androiddebugkey -keystore debug.keystore -storepass android -keypass android

or

b) generate a Release certificate:


keytool -list -keystore debug.keystore

 

3. Copy the generated MD5 fingerprint and navigate to http://code.google.com/android/maps-api-signup.html to get the Map key.

Creating a simple Gesture Application in Android

January 10, 2012 23 comments

Android supports the Gesture API since version 1.6. The API can be located in the package android.gesture, and lets you store, load, draw and recognize gestures. This tutorial will show you a proof-of-concept application how you can make use of Gesture API.

We will define 2 gestures: “S” and “O”. When a corresponding gesture will be recognized, a toast message will be shown.

The result will look like in the screenshot below:

Create a new project:
Project: AndroidGesture
Activity: AndroidGestureActivity

1. Creating the gestures
Starting with version 1.6 and higher the Android Emulator includes a new application pre-installed, called Gestures Builder.

Start the Android Emulator and use the Gesture Builder application to create the “S” and “O” gestures:

Android Gesture

A gesture is always associated with a name, but the name does not necessarily have to be unique. In fact, it’s recommended to have several gestures with the same name to increase the precision of recognition.

2. Importing gesture to your project
Every time we create or edit gestures with Gesture Builder, a file is created on the emulator SD card: /sdcard/gestures. We should import this file into our /res/raw project directory.

In order to do this, open the FileExplorer tab in the DDMS perspective. (If you don’t have the FileExplorer tab available, add it from: Window -> Show View -> File Explorer). Navigate to /sdcard directory and copy the gesture file to your computer, for example on your desktop.

To copy the gesture file from the emulator, select it and click the “Pull a file from the device” button, marked with red in the screenshot below:

Android DDMS

Don’t forget to create a new folder called raw in the res directory of your project and copy there the gesture file.

3. Loading the gesture library and recognizing the gesture
To start recognizing gesture in our application we have to add the GestureOverlayView to our XML layout file. There are 2 ways you can use the GestureOverlayView, one of them is to use it as a normal view embedded inside a LinearLayout for example, and another is to use it as an overlay on top of other views. In this tutorial we will use the second option – an overlay on top of other views.

Edit the main.xml layout to look like this:


<?xml version="1.0" encoding="utf-8"?>
<android.gesture.GestureOverlayView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/gestures"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:eventsInterceptionEnabled="true"
android:gestureStrokeType="multiple"
android:orientation="vertical" >

<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView" />

</android.gesture.GestureOverlayView>

Make the AndroidGestureActivity to implement the OnGesturePerformedListener interface and add the the mLibrary member variable of type GestureLibrary:

public class AndroidGestureActivity extends Activity implements OnGesturePerformedListener {
GestureLibrary mLibrary;

In the onCreate() method we load the library and add the GestureOverlayView to the listener:

@Override
public void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   setContentView(R.layout.main);

   mLibrary = GestureLibraries.fromRawResource(this, R.raw.gestures);
   if (!mLibrary.load()) {
     finish();
   }

   GestureOverlayView gestures = (GestureOverlayView) findViewById(R.id.gestures);
   gestures.addOnGesturePerformedListener(this);
}

And below is the implementation of onGesturePerformed(). When the listener is triggered, a list of predictions and a score is returned, each with the name you entered earlier in the Gesture Builder. The list is sorted by descending scores; the higher the score, the more likely the associated gesture is the one the user intended to draw:

public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) {
   ArrayList<Prediction> predictions = mLibrary.recognize(gesture);

   if (predictions.size() > 0 && predictions.get(0).score > 1.0) {
     String result = predictions.get(0).name;

     if ("open".equalsIgnoreCase(result)) {
       Toast.makeText(this, "Opening the document", Toast.LENGTH_LONG).show();
     } else if ("save".equalsIgnoreCase(result)) {
       Toast.makeText(this, "Saving the document", Toast.LENGTH_LONG).show();
     }
   }
}

By this time the application should compile and run successfully.

Reference: http://developer.android.com/resources/articles/gestures.html

Follow

Get every new post delivered to your Inbox.

Join 516 other followers

%d bloggers like this: