Saturday, October 31, 2009

Deploying Android package (.apk) into Mobile Device from Eclipse IDE

Feeling very frustrated trying to understand the deployment guidelines in the Android SDK website, I am writing this article to share my knowledge and experience in deploying Android applications from Eclipse into Android-powered mobile devices in Debug Mode to the readers who are also interested in developing Android applications. I have not explore the processes of signing an Android application for Public Release Mode, yet.

A major correction:
You can actually deploy your Android application without signing it in Debug Mode. Simply follow these steps and you are ready to test your application.

Things to do with the mobile device:
1. Press Menu button
2. Tap on Settings button
3. Tap on Applications in the menu
4. Put a check for Unknown Sources (to allow installation of non-Market applications)
5. Tap on Development (to set options for application development)
6. Put a check on USB debugging (to enable the Debug Mode when USB is connected)
7. Press Back button to go back to to the Settings menu
8. Plug your USB cable into the computer

Things to do with the console:
1. Go to the bin directory that places the APK file.
2. Type adb install

Optional:
You may do zipalign in the console if you wish to do so.

I hope this article is useful and informative enough for the Android developer community. Please leave your comments in the comments section if this does not work for you.

UPDATE: you may actually deploy your Android app by right-clicking at your project name. Select "Run As" and then click at "Android Application."

As simple as that. :)

Wednesday, October 28, 2009

Motorola Droid (Android 2.0)

The Droid looks fancy but I think any smartphones will look a lot more attractive with some shades of metallic coating or aluminum casing. This is the video from CNET showcasing Motorola Droid.

Search Assistant in Splunk 4

Being a software developer whose passion evolves about search, mobile applications and analytics and love to look at log files, I find that the most useful and technically attractive feature as I play along with the free version of Splunk> is the Search feature. It is so helpful that contextual suggestions will be given to you as you type your search phrases in the textfield. Initially I was completely clueless about how to perform a search.

The screenshots are as shown below. The top most image is the untouched search string. At first I was afraid to type anything into the textfield having the similar fear that Google might crash if we search for "google". Nah ... just kidding:P As a fail-safe software developer I assume that Splunk has an excellent exception handlings. However, I tried searching for the usage manual but I did not know how to search for it (for example the appropriate search strings to search for the manual and such).Imagine myself greeting you "Hi, this is Nicholas Key and I'm a software engineer. EEErrrggghhh..."This video provides you an excellent way to get started, in my opinion.


Update: Actually there is an introduction that teaches you how to use the Search feature but I overlooked it. Instead of clicking at Getting Started, I clicked at *NIX. You may find a brief explanation about using various techniques to perform search. Screenshots are as below:

My Java codes in Python (Part 3)

Prologue: I feel like making a tag cloud for the labels of my articles ;)

My Java codes in Python (Part 2)

Tuesday, October 27, 2009

Another Web Journal Success (my personal minor achievement)

Web Journal is ranked top in Korean language for blog search. I can understand some Korean words and if I'm not mistaken, the Korean words in the header area literally means "Blog".

Splunk> User Interface

Here I am at the login page of Splunk>. The username/password is admin/changeme by default. You will have to click at the "First time signing in?" link to get the clue ;)
I think that the UI is really welcoming and slick. The snapshot is as below.
Since I feel like first trying out the *NIX application, I'll have to enable the feature before launching it. Even the AJAX powered loading modal looks impressive. Don't believe me? Take a look at it yourself :)

Trying out Splunk> 4.0.5 build 69401

This is my first time trying out an intelligent application that helps you monitor the content of your log files. Let's see how much I progress being a new user installing this application.

[1] Downloading a copy of Splunk>
This is the URL if you want to try out the free version of Splunk>. There are many choices of platforms for you to choose. I chose the MacOS 10.5 version and downloaded the DMG file. The version that I downloaded when I first wrote this article is splunk-4.0.5-69401-macosx-10.5-universal.dmg
[2] Installing Splunk>
If you are stumped trying to install Splunk>, there is a wiki page at your convenience. Click here to take a look at their help page and then select the appropriate version of the copy you downloaded. I clicked at version 4.0.5 and selected the link that guides me how to install it into my computer.
[3] Installation steps
The installation was a breeze until I wanted to launch it. According to the manual, I'll have to type this out $INSTALLATION_DIRECTORY/bin/splunk start. It did not work but I had this "gotcha" moment and did a ./splunk start and it worked just fine. You do not actually need to do $INSTALLATION_DIRECTORY/bin/splunk start --accept-license because you'll have to agree with the agreement during the installation by typing y (the second picture illustrates that).
[4] Installation process completed
I was shown these lines at the bottom of the output:

If you get stuck, we're here to help.
Look for answers here: http://www.splunk.com/base/Documentation

The Splunk web interface is at http://nicholas-keys-macbook-pro.local:8000

[5] There's no step 5 :P
Just kidding. The fifth step is to start exploring the features of Splunk> and understand why it is good as how people claim it is. Splunk's themes are very catchy and I particularly like this theme "Finding your faults just like mum". Sample snapshot of Splunk> in my browser is shown below.

CustomStack upgrades

My CustomStack now comes with several other new features. I can actually check if an Object exists in the Stack. Once the Object is found, a boolean true is returned. In addition to that, I've also added a method to retrieve an element with a given 0-based index number. I call it elementAt and it has a similar functionality of get. To the readers who are accustomed to the methods of a Stack, I have also added the method peek. Basically, it's a method to retrieve the element at the top of the Stack. The method search returns the 0-based index number of the first found element and -1 is returned if the element is not found. Here are the summary of methods of the newly improved CustomStack:
contains(Object input)
elementAt(int index)
peek()
search(Object input)

Below is the code snippet.

public boolean contains(Object input){
boolean found = false;
if(empty()){
throw new RuntimeException( "Stack is already empty. No elements to check." );
}
for(int i = 0; i<size(); i++) {
if (stackElements[i].hashCode() == input.hashCode()) {
found = true;
break;
}
}
return found;
}

public Object elementAt(int index){
return get(index);
}

public Object peek(){
return top();
}

public int search(Object input){
int index = -1;
if(empty()){
throw new RuntimeException( "Stack is already empty. No elements to search." );
}
for(int i = 0; i<size(); i++) {
if (stackElements[i].hashCode() == input.hashCode()) {
index = i;
break;
}
}
return index;
}

Click here to view the previous code of CustomStack.

Monday, October 26, 2009

Stack Implementation in Java

Below is my code to implement Stack from ground-up. I tried (in a very short time) to emulate the behavior of Stack in the Java Util package. The methods I have written are:
size()
get(int index)
empty()
clear()
pop()
push(Object input)
bottom()
top()


I call my Stack implementation as CustomStack as it may evolve over time. I have also provided some test cases to validate that the implementation actually works. The sample output is shown below the codes.

import java.lang.reflect.Array;

public class CustomStack {

private Object[] stackElements;
private int stackIndex = -1;
private int stackSize = 0;
private static final int INIT_SIZE = 3;
private boolean stackSizeGiven = false;
private int sizeHolder = 0;

public CustomStack(){
stackElements = new Object[ INIT_SIZE ];
stackSizeGiven = false;
}

public CustomStack(int inputSize){
sizeHolder = inputSize;
stackElements = new Object[ sizeHolder ];
stackSizeGiven = true;
}

public int size(){
return stackSize;
}

public Object get(int index){
if ((index < 0) || (index > (stackSize))) {
throw new RuntimeException("Index out of bound. Supplied " + index);
}
return stackElements[ index ];
}

public boolean empty() {
return stackIndex == -1;
}

public void clear() {
if (stackSizeGiven) {
stackElements = new Object[ sizeHolder ];
} else {
stackElements = new Object[ INIT_SIZE ];
}
stackIndex = -1;
stackSize = 0;
}

public void pop() {
if(empty()){
throw new RuntimeException( "Stack is already empty. No elements to pop." );
}
stackIndex--;
stackSize--;
}

public void push(Object input) {
if( stackIndex + 1 == stackElements.length ) {
int arrayLength = Array.getLength(stackElements);
Object [] newArray = (Object[]) Array.newInstance(stackElements.getClass().getComponentType(), (arrayLength + arrayLength ));
System.arraycopy(stackElements, 0, newArray, 0, arrayLength);
stackElements = newArray;
}
stackElements[ ++stackIndex ] = input;
stackSize++;
}

public Object bottom(){
if(empty())
throw new RuntimeException( "Stack is already empty. No elements at bottom." );
return stackElements[ 0 ];
}

public Object top() {
if(empty())
throw new RuntimeException( "Stack is already empty. No elements at top." );
return stackElements[ stackIndex ];
}

public static void testCases(){
CustomStack aStack = new CustomStack();
System.out.println("Stack is empty: " + aStack.empty());
aStack.push("Nicholas Key");
aStack.push(3.142);
aStack.push(false);
// Prints false
System.out.println("Element at top of Stack: " + aStack.top());
System.out.println("Size of current Stack: " + aStack.size());

aStack.push("Java Developer");
aStack.push("Android App Developer");
// Prints Android App Developer
System.out.println("Element at top of Stack: " + aStack.top());

aStack.push("Web App Developer");
aStack.push("Blogger");
aStack.push(2009);
// Prints 2009
System.out.println("Element at top of Stack: " + aStack.top());
System.out.println("Size of current Stack: " + aStack.size());

// Prints Stack elements
for (int i= 0; i< aStack.size(); i++) {
System.out.println("Index " + i + ": " + aStack.get(i));
}

// Pops 2009
aStack.pop();
// Prints Blogger
System.out.println("Element at top of Stack: " + aStack.top());

// Pops Blogger
aStack.pop();
// Prints Web App Developer
System.out.println("Element at top of Stack: " + aStack.top());

// Prints Stack elements
for (int i= 0; i< aStack.size(); i++) {
System.out.println("Index " + i + ": " + aStack.get(i));
}

System.out.println("Element at bottom of Stack: " + aStack.bottom());

// Pops out all Stack elements
aStack.clear();
System.out.println("Stack is empty: " + aStack.empty());

System.out.println(aStack.get(1));

System.out.println(aStack.get(aStack.size() + 300));
}

public static void main(String[] args) {
testCases();
}
}

Stack is empty: true
Element at top of Stack: false
Size of current Stack: 3
Element at top of Stack: Android App Developer
Element at top of Stack: 2009
Size of current Stack: 8
Index 0: Nicholas Key
Index 1: 3.142
Index 2: false
Index 3: Java Developer
Index 4: Android App Developer
Index 5: Web App Developer
Index 6: Blogger
Index 7: 2009
Element at top of Stack: Blogger
Element at top of Stack: Web App Developer
Index 0: Nicholas Key
Index 1: 3.142
Index 2: false
Index 3: Java Developer
Index 4: Android App Developer
Index 5: Web App Developer
Element at bottom of Stack: Nicholas Key
Stack is empty: true
Exception in thread "main" java.lang.RuntimeException: Index out of bound. Supplied 1
at CustomStack.get(CustomStack.java:29)
at CustomStack.testCases(CustomStack.java:128)
at CustomStack.main(CustomStack.java:136)
Update: I've added several methods to make my CustomStack more robust ;) Click here to look at the improvements.

Sunday, October 25, 2009

What happens when you type in a URL into the browser ...

These are the processes taken place.
[Immense credits to EXPRESS HOST PRO for the detailed explanation]
Step 1: Request a record
You begin by asking your computer to resolve a hostname, such as visiting 'http://www.google.com' in a web browser. The first place your computer looks is its local DNS cache, which stores DNS information that the computer has recently retrieved.

Step 2: Ask the Recursive DNS servers
If the records are not stored locally, your computer queries (or contacts) your ISP's recursive DNS servers. These machines perform the legwork of DNS queries on behalf of their customers. The recursive DNS servers have their own caches, which they check before continuing with the query.

Step 3: Ask the Root DNS servers
If the recursive DNS servers do not have the record cached, they contact the root nameservers. These thirteen nameservers contain pointers for all of the Top-Level Domains (TLDs), such as '.com', '.net' and '.org'. If you are looking for 'www.google.com.', the root nameservers look at the TLD for the domain - 'www.google.com'- and direct the query to the TLD DNS nameservers responsible for all '.com' pointers.

Step 4: Ask the TLD DNS servers
The TLD DNS servers do not store the DNS records for individual domains; instead, they keep track of the authoritative nameservers for all the domains within their TLD. The TLD DNS servers look at the next part of the query from right to left - 'www.google.com' - then direct the query to the authoritative nameservers for 'google.com'.

Step 5: Ask the Authoritative DNS servers
Authoritative nameservers contain all of the DNS records for a given domain, such as host records (which store IP addresses), MX records (which identify nameservers for a domain), and so on. Since you are looking for the IP address of 'www.google.com', the recursive server queries the authoritative nameservers and asks for the host record for 'www.google.com'.

Step 6: Retrieving the record
The recursive DNS server receives the host record for 'www.google.com' from the authoritative nameservers, and stores the record in its local cache. If anyone else requests the host record for 'www.google.com', the recursive servers will already have the answer, and will not need to go through the lookup process again until the record expires from cache.

Step 7: The Answer!
Finally, the recursive server gives the host record back to your computer. Your computer stores the record in its cache, reads the IP address from the record, then passes this information to the web browser. Your browser then opens a connection to the IP address '72.14.207.99' on port 80 (for HTTP), and our webserver passes the web page to your browser, which displays Google.

You may visit the original content at this URL.

Here's my understanding to the processes:

We type in a URL and hit GO.
The browser translates the URL into an IP address.
In order to do that, the browser contacts DNS to resolve the IP address.
The browser checks if the IP address is cached.
If not, it makes a DNS query to my ISP's DNS server.
DNS replies back with the IP address of the site.
Browser opens TCP connection to the server at port 80.
Displays the content in browser.
Stores the IP address in the DNS cache for future use.
When the browser is closed, TCP connection is terminated.

The HTTP request being made is a GET request.
Correct me if I'm wrong.

Saturday, October 24, 2009

Steve Ballmer on Windows 7

Tell me you are not seeing the MacBook Pro at the big LCD screen. While it is true that you can actually operate Windows on a Mac provided that you installed VMware, I really think that one of the many other OEM brands is more appropriate to be shown in that big screen.Take a look at Steve's face when he is holding the Dell Adamo XPS notebook. I guess he must be thinking "Why is this guy shoving a MacBook Air to me? I feel like snapping this notebook into halves. It reminds me ths fragility of the Air!" Look at his face again :) Priceless! :P

Pictures are attributed to NBC.

Friday, October 23, 2009

Sorting Algorithms (Bubble sort, Selection sort & Insertion Sort)

I want to refresh my mind about sorting algorithms and here are the first three simple sorting algorithms in this article - Bubble Sort, Selection Sort and Insertion Sort. I attribute the explanations to Wikipedia.

import java.util.Random;

public class SortingAlgorithm {

private final int SIZE = 2000;
private Random myRand = new Random();
private int[] numbers = new int[SIZE];

public SortingAlgorithm(){}

private void randomizeNumbers(){
for (int i = 0; i < numbers.length; i++) {
numbers[i] = myRand.nextInt( 2000 ) + 1;
}
}

private void printArray(){
for(int i: numbers){
System.out.print(i + " ");
}
System.out.println();
}

public void bubbleSort() {
randomizeNumbers();
System.out.println("BUBBLE SORT");
System.out.println("Presorted numbers: ");
printArray();
long start = System.nanoTime();

/**
* Bubblesort algorithm
* Wikipedia:
* works by repeatedly stepping through the list to be sorted,
* comparing each pair of adjacent items and swapping them if
* they are in the wrong order. The pass through the list is
* repeated until no swaps are needed, which indicates that the
* list is sorted. The algorithm gets its name from the way smaller
* elements "bubble" to the top of the list.
* Complexity:
* Worst = O(n^2)
* Average = O(n^2)
* Best = O(n)
*/
int n = numbers.length;
for (int pass=1; pass < n; pass++) {
for (int i=0; i < n-pass; i++) {
if (numbers[i] > numbers[i+1]) {
int temp = numbers[i];
numbers[i] = numbers[i+1];
numbers[i+1] = temp;
}
}
}

long elapsed = (System.nanoTime() - start);
System.out.println("Bubble-sorted numbers: ");
printArray();
System.out.println("Elapsed time: " + elapsed + "ns\n");
}

public void selectionSort(){
randomizeNumbers();
System.out.println("SELECTION SORT");
System.out.println("Presorted numbers: ");
printArray();
long start = System.nanoTime();

/**
* Selectionsort Algoritm
* Wikipedia:
* 1. Find the minimum value in the list
* 2. Swap it with the value in the first position
* 3. Repeat the steps above for the remainder of the list (starting
* at the second position and advancing each time)
* Complexity:
* Worst = O(n^2)
* Average = O(n^2)
* Best = O(n^2)
*/
for (int i=0; i<numbers.length-1; i++) {
int minIndex = i;
for (int j=i+1; j<numbers.length; j++) {
if (numbers[minIndex] > numbers[j]) {
minIndex = j;
}
}
if (minIndex != i) {
int temp = numbers[i];
numbers[i] = numbers[minIndex];
numbers[minIndex] = temp;
}
}

long elapsed = (System.nanoTime() - start);
System.out.println("Selection-sorted numbers: ");
printArray();
System.out.println("Elapsed time: " + elapsed + "ns\n");
}

public void insertionSort(){
randomizeNumbers();
System.out.println("INSERTION SORT");
System.out.println("Presorted numbers: ");
printArray();
long start = System.nanoTime();

/**
* Insertionsort Algorithm
* Wikipedia:
* much less efficient on large lists than more advanced algorithms
* such as quicksort, heapsort, or merge sort. However, insertion sort
* provides several advantages:
* 1. simple implementation
* 2. efficient for (quite) small data sets
* 3. adaptive, i.e. efficient for data sets that are already substantially
* sorted: the time complexity is O(n + d), where d is the number of inversions
* 4. more efficient in practice than most other simple quadratic (i.e. O(n^2)) algorithms
* such as selection sort or bubble sort
* Complexity:
* Worst = O(n^2)
* Average = O(n^2)
* Best = O(n)
*/
int in, out;
for(out=1; out<numbers.length; out++){
int temp = numbers[out];
in = out;
while(in>0 && numbers[in-1] >= temp){
numbers[in] = numbers[in-1];
--in;
}
numbers[in] = temp;
}

long elapsed = (System.nanoTime() - start);
System.out.println("Insertion-sorted numbers: ");
printArray();
System.out.println("Elapsed time: " + elapsed + "ns\n");
}

public static void main(String[] args) {
SortingAlgorithm sa = new SortingAlgorithm();
sa.bubbleSort();
sa.selectionSort();
sa.insertionSort();
}
}

BFS and DFS (intro)

BFS:
- works in a queue manner (FIFO)

DFS:
- works in a stack manner (LIFO)

Thursday, October 22, 2009

Web Journal's Ranking in Google Blog Search

Tell me you would be very happy if you are a blogger yourself and your blog is ranked top in the search result. I am thrilled to see this ;) Thanks to all the readers who make this possible.

Mirror by Jonas

This is a very special segment of my blog because I'm helping a reader of my blog to promote his API about Java Reflection. Many thanks to Jonas for coming up with such convenient API. You may take a look at his project "Mirror" at this link.
I would want to liken this Mirror API it to using Velocity to generate dynamic HTML in a sense that it eases your coding complexity.

Wednesday, October 21, 2009

Traversing Folder and Files

Here is an updated code to inform you if the file or folder specified does not exists. You may take a look at the original code at this article.


public void traverseFilesFolders () {
if (referencedFile.exists()) {
traverseFilesFolders(referencedFile);
} else {
System.out.println("File or Folder does not exist");
}
}

Final vs Finally vs Finalize

A short note for myself:

Final: used for defining a class non-subclassable, and making a member variable as a
constant which cannot be modified, and declare a method non-overridable.

Finally: to provide the capability to execute code no matter whether or
not an exception is thrown or caught in the try-catch exception handler.

Finalize: helps in garbage collection to clean up objects that are no longer required. Usualy Java will do the garbage collection automatically.

Monday, October 19, 2009

Java Reflection

The Reflection API allows the user to get the complete, but not limited to, information about classes, constructors, interfaces and methods that are being used. There are many things we can achieve with this API and the methods are:
getInterfaces()
getName()
getClass()
getSuperclass()
getMethods()
getFields()
getConstructors()

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class ReflectionTool {

private static final String padding = "\t";

public void retrieveInterfaces(){
System.out.println("Retrieve Interface(s):");
for (Class anInterface: java.util.Date.class.getInterfaces()) {
System.out.println(padding + anInterface);
}
}

public void retrieveName(){
System.out.println("Retrieve Name of Class:");
System.out.println(padding + java.util.concurrent.atomic.AtomicInteger.class.getName());
}

public void retrieveClass(){
System.out.println("Retrieve Runtime Class:");
System.out.println(padding + java.util.zip.CRC32.class.getClass());
}

public void retrieveSuperClass(){
System.out.println("Retrieve Superclass:");
System.out.println(padding + java.util.zip.CRC32.class.getClass().getSuperclass());
}

public void retrieveMethods(){
System.out.println("Retrieve Methods:");
for (Method aMethod: java.util.List.class.getMethods()) {
System.out.println(padding + aMethod);
}
}

public void retrieveFields(){
System.out.println("Retrieve Fields:");
for (Field aField: java.lang.Double.class.getFields()) {
System.out.println(padding + aField);
}
}

public void retrieveConstructors(){
System.out.println("Retrieve Constructors:");
for (Constructor aConstructor: java.lang.Double.class.getConstructors()) {
System.out.println(padding + aConstructor);
}
}

public static void main(String[] args) {
ReflectionTool rt = new ReflectionTool();
rt.retrieveInterfaces();
rt.retrieveName();
rt.retrieveClass();
rt.retrieveSuperClass();
rt.retrieveMethods();
rt.retrieveFields();
rt.retrieveConstructors();
}
}

The output of the code is as follow. Nothing fancy, nothing complicated. Everything is straightforward.

Retrieve Interface(s):
interface java.io.Serializable
interface java.lang.Cloneable
interface java.lang.Comparable
Retrieve Name of Class:
java.util.concurrent.atomic.AtomicInteger
Retrieve Runtime Class:
class java.lang.Class
Retrieve Superclass:
class java.lang.Object
Retrieve Methods:
public abstract int java.util.List.hashCode()
public abstract boolean java.util.List.equals(java.lang.Object)
public abstract java.lang.Object java.util.List.get(int)
public abstract boolean java.util.List.add(java.lang.Object)
public abstract void java.util.List.add(int,java.lang.Object)
public abstract int java.util.List.indexOf(java.lang.Object)
public abstract void java.util.List.clear()
public abstract int java.util.List.lastIndexOf(java.lang.Object)
public abstract boolean java.util.List.contains(java.lang.Object)
public abstract boolean java.util.List.addAll(java.util.Collection)
public abstract boolean java.util.List.addAll(int,java.util.Collection)
public abstract int java.util.List.size()
public abstract java.lang.Object[] java.util.List.toArray()
public abstract java.lang.Object[] java.util.List.toArray(java.lang.Object[])
public abstract java.util.Iterator java.util.List.iterator()
public abstract java.lang.Object java.util.List.set(int,java.lang.Object)
public abstract boolean java.util.List.remove(java.lang.Object)
public abstract java.lang.Object java.util.List.remove(int)
public abstract boolean java.util.List.isEmpty()
public abstract boolean java.util.List.containsAll(java.util.Collection)
public abstract boolean java.util.List.removeAll(java.util.Collection)
public abstract boolean java.util.List.retainAll(java.util.Collection)
public abstract java.util.List java.util.List.subList(int,int)
public abstract java.util.ListIterator java.util.List.listIterator()
public abstract java.util.ListIterator java.util.List.listIterator(int)
Retrieve Fields:
public static final double java.lang.Double.POSITIVE_INFINITY
public static final double java.lang.Double.NEGATIVE_INFINITY
public static final double java.lang.Double.NaN
public static final double java.lang.Double.MAX_VALUE
public static final double java.lang.Double.MIN_VALUE
public static final int java.lang.Double.SIZE
public static final java.lang.Class java.lang.Double.TYPE
Retrieve Constructors:
public java.lang.Double(double)
public java.lang.Double(java.lang.String) throws java.lang.NumberFormatException


Friday, October 16, 2009

Traversing Folders and Files Recursively

Both files and folders are represented as File object in the java.io package. We are recognizing if an object is a file by using the method "isFile()" and a folder with the method "isDirectory()".

import java.io.File;

public class FilesFoldersTraversal {

private final char SEPARATOR = File.separatorChar;
private File originalFile;
private File referencedFile;
private String pad = null;
private String absolutePathOriginalFile = null;

public FilesFoldersTraversal(String inputFileString) {
File inputFile = new File(inputFileString);
originalFile = inputFile;
referencedFile = inputFile;
absolutePathOriginalFile = originalFile.getAbsolutePath();
}

public void traverseFilesFolders () {
traverseFilesFolders(referencedFile);
}

private void traverseFilesFolders(File referencedFile){
if (referencedFile.isDirectory()){
pad = getPadding(referencedFile);
processFolders(referencedFile);
}
else if (referencedFile.isFile()){
processFiles(referencedFile);
}
}

private void processFolders(File referencedFile){
System.out.println(pad + "Folder: " + referencedFile.getName());
File listFiles[] = referencedFile.listFiles();
for(File singleFile : listFiles){
traverseFilesFolders(singleFile);
}
}

private void processFiles(File referencedFile){
System.out.println(pad + " " + "File: " + referencedFile.getName());
}

private String getPadding(File referencedFile){
String padding = "";
String fileAbsolutePath = referencedFile.getAbsolutePath();
String filePathSubString = fileAbsolutePath.substring(absolutePathOriginalFile.length(), fileAbsolutePath.length());

int index = 0;
int subStringLength = filePathSubString.length();
while (index < subStringLength) {
if (filePathSubString.charAt(index) == SEPARATOR){
padding += " ";
}
index++;
}

return padding;
}

public static void main(String[] args) {
FilesFoldersTraversal fft = new FilesFoldersTraversal("/Users/YOUR_USER_NAME/Documents");
fft.traverseFilesFolders();
}

}
There are many interesting things you can do with the example shown. You may add a few lines of codes to compile a list of files of a specific file extension, for example ".txt" or ".class".

Thursday, October 8, 2009

MediaPlayer vs SoundPool

Here is my recommendation if you are not sure which class to use - MediaPlayer or SoundPool when developing an Android application.

MediaPlayer:
If you were to play a background music in your application, you should go for MediaPlayer. MediaPlayer is my preferred class because it allows you to playback a lengthy audio file.

SoundPool:
As the name explains itself, SoundPool class allows you to playback a collection of short sound effects quickly and it does not lag much. Imagine yourself writing a game with several sound effects meant for different actions. You may use a HashMap to compile the list of SFXs and then play it by accessing the index number (key in the HashMap).

Summary:
Notice the adjectives I used for different classes.
Lengthy, theme = MediaPlayer
Short, effect = SoundPool

Monday, October 5, 2009

Reading XML in Android platform

I find these XmlResourceParser and XmlPullParser classes useful to read XML files when we are dealing with Android platform. Below is the code sample I use in my Android project:Here is an example from the Android Developers website.

Detailed explanation of using XSL to scrape ISO country codes

I apologize if you couldn't understand how I managed to scrape the country codes from the ISO website as mentioned in my previous article. Here are the detailed steps to scrape the codes accordingly. You'll need 3 things to achieve the goal: manual editing (I know it's primitive otherwise you are more than welcomed to write your HTML tag stripper to recognize the elements in the web page), XML file and XSL file.

[1] Copy the table element:
- Copy the entire table element that contains the country names and codes

[2] Editing the XML file:
- Open an empty file
- Save it as "countries.xml"
- Add this line at the top of the XML file:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="countries.xsl"?>
- Paste the table element you copied earlier
- Remove the table row that contains "Country names" and "ISO 3166-1-alpha-2 code"
- The screenshot is as below:[3] Editing the XSL file:
- Copy the XPath codes I demonstrated in this article
- Save it as "countries.xsl"

[4] You are all set!
- Here is the sample output translating the XML using XPath