Tuesday, October 20, 2009

Launching Android in Eclipse

Have you had to select "Android Application" EVERY TIME you hit Ctrl+F11 to launch your android application?? Yea i agree... its annoying.

Well, just goto Window -> Preferences -> Run/Debug -> Launching

Right at the bottom you'll find a section called "Launch Operation".
Select: Launch the selected resource or active editor. If not launchable:
Select: Launch the previously launched application.

Its that second option that makes all the difference. Every time to hit Ctrl+F11, eclipse cannot find a launcher for the "active editor". So now it will default to the last launched config which should be the same application.

But you do have to create and run a launch configuration first. Also a drawback here would be that you cannot co-develop two android projects and expect to run them at your will.... there's always a catch. (sigh)

Overriden or Implemented?

When you override or implement a method, eclipse puts that annoying @Override annotation on it. I understand annotating methods that are actually overriding the superclass methods, but why on implemented methods?

Anyway, there is another way to differentiate between these methods. Eclipse puts an arrow (pointing up) in the sidebar next to every overridden/implemented method. Next to any overridden method, this arrow is filled in green, indicating a previous implementation by a super class. Implemented methods have a plain empty arrow.

Thursday, October 15, 2009

Searching Nearby in Android

Using google's geocoder in android is not much fun. It does your basic conversion between coordinates and addresses but to find a business nearby specific coordinates, is a whole different game altogether. From what I gather, there are two ways to get this done:

1) I've heard the Yahoo geocoder library has this functionality but who uses Yahoo to find a starbucks anyway?
2) Query Google Maps for the information

Im gonna discuss option 2. Steps involved are: query google maps, get our data, parse.

First we create a URL object:

URL url = new URL("http://maps.google.com/maps?q=your+query+here");

SIDENOTE:
the 'your+query+part' is where you want to put what you want to find. Its really simple... play around with the website and you'll see the URL in the browser change everytime you type in an address or search for something. A simple example is when I want to search for food near some latitude & longitude, my query string will be:

q=food+loc:+latitude+longitude

Don't forget to use + for spaces, and latitude & longitude are in double format. You also would want to get the information back in some form so you could parse through it. To achieve this, add the 'output' variable to your query string. Goto http://mapki.com/wiki/Google_Map_Parameters for an explanation of all the different paramaters and their usage. So finally, our URL becomes:


"http://maps.google.com/maps?q=food+loc:latitude+longitude&output=kml" (for a kml output)


Back to the code:

URLConnection conn = url.openConnection();
InputStream in = conn.getInputStream(); // Google will send you the KML data via this input stream

From here on out I don't really understand how the tree is built, what nodes and node elements are, but I could extract the information I was looking for with the following lines of code:

// Now to build the document tree by parsing the inputStream.
Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(in);
document.getDocumentElement().normalize();

// Each result of your query is placed in a placemark tag
NodeList
placemarks = document.getElementsByTagName("Placemark");



for (Node item : placemarks)
if (item.getNodeType() == Node.ELEMENT_NODE) {
Element element = (Element) item;

String tagName = "name"; // Name of each placemark or business
NodeList childNodes = element.getElementByTagName(tagName);
Element nameElement = childNodes.item(0);
String tagValue = nameElement.getChildNodes().item(0).getNodeValue();
}



To retrive additional information from your KML, substitute tagName with:

"address" - to get address of each result. tagValue will then contain the html form of the address, meaning that each address line will be separated with <br/>. You can use the replaceAll(String, String) method in the String class to replace all instances of <br/> with "\n" or maybe ",".

"coordinates" - gets the latitude and longitude of each result.

"Snippet" - this gets you the phone number but after an additional step. Use the split(String) method in the String class to split tagValue into an array of sub-strings at <br/> and the phone number will ALWAYS be the second item in the resulting array.

And that's it! Now you can search for stuff around you using the GPS and querying Google. The only downside to this technique the cost involved in transferring the data back to your phone over the network.

Eclipse Auto Formatting

If you like your code formatted, indented neatly, imports arranged, etc. every time you edit your programs, this is one shortcut I find very effective:

Goto: Window -> Preferences
Select Java -> Editor -> Save Actions

On the right are actions that you can ask Eclipse to perform every time you hit Ctrl + S. Besides the basic options click on "Configure" to add formatting actions and other misc stuff.

This way you don't have to worry about Ctrl-Shift F, Ctrl-Shift-O or any other shortcut, except Ctrl-S to save, which you probably know since 6th grade.

Android Internationalization

To provide internationalization of your applications on Android, all you have to do is create "values" folders for each language you wish to implement.

Eg: If your application supports English and Spanish, then you would have the default "values" folder for English, and "values-es" for spanish. You can then create a "strings.xml" for each folder and put your language specific strings in them. Be sure that your strings have the same "name" attribute across each folder. If the phone is configured in Spanish, and the user clicks on your application, Android will automatically read the "values-es" folder for strings.

Im not sure about this, but it is my guess that this can be extended for other folders as well. That way, you can have one logical code base, but can have multiple layouts, strings, colors etc.

What I am sure off, is that this functionality can also be extended for different devices that have different hardware and settings. You have just append the right qualifies to your "values" folder.

If you goto: File -> New -> Other -> Android -> Android XML File

After you choose your .xml filename, and you select the type of resource, you then have a list of qualifiers which you can choose, and for each qualifier you can enter the value in the textbox.

So for the above example, I would type "strings.xml" as the filename, Select "values" as the resource type, choose the "Language" qualifier, and for Spanish I will type "es" in the textbox and click "Finish". Android will then create my srings.xml file in /res/values-es.

For more information on Android resources and internationalization, check this out: http://developer.android.com/guide/topics/resources/resources-i18n.html