Archive

Archive for the ‘Tutorials’ Category

Create application with Swipe gesture to navigate page like Google Play

December 26, 2012 4 comments

Android users might already have been familiar with Google Play application, which first, I think,  inspires the pattern of horizontal swipe gesture to navigate among content pages.

This article is gonna show you how to do a very very quick simple application that does the same pattern.

Swipe Pattern Sample

Swipe Pattern Sample

There will be three pages, each page will display a sample image of that page as swiping along. My sample, I put: “Girl, Dog & Cat”.

A – Requirements

– ViewPagerIndicator library, you can get it from here: http://viewpagerindicator.com/

– Android Support Package Library v4, well, you can either download the above package and use the already-had libs or get it from SDK Update. Either way is fine.

B – Project

Well, since I’m an Ant user, I prefer to do stuffs in command-line, so this tutorial will probably in command-mode.

1. Create the project

$ create project --target 2 --name Droid05 --path ./Droid05 --activity MainScreen --package pete.apps.study.droid05

Now project is ready for the next step.

2. Configure libs

– After downloading the ViewPagerIndicator package, you need to update the library in order to get Ant build.xml for the job. Please refer to my previous post: https://xjaphx.wordpress.com/2012/12/26/build-viewpagerindicator-with-ant/
– Now go to config the library reference, edit the project.properties and add this line

android.library.reference.1=../../tools/frameworks/ViewPagerIndicator/library

that is my case, you should locate to your correct directory where you put the /library of the ViewPagerIndicator.
– To test the config, you can just type to confirm

$ ant clean debug

If it succeeds, it means fine.
3. Implement the code
– Create the layout, pretty much simple, there will use a TitlePageIndicator and a ViewPager, main.xml

$ vi res/
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="#FFFFFFFF"
    >
    <com.viewpagerindicator.TitlePageIndicator
        android:id="@+id/titles"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="#FFFFFFFF"
        android:textColor="#FF000099"
        app:footerColor="#FF00FF00"
        app:footerLineHeight="3dp"
        app:footerIndicatorHeight="6dp"
        app:footerIndicatorStyle="triangle"
        app:selectedColor="#FF0000FF"
        app:selectedBold="true"
    />
    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
    />
</LinearLayout>

– Create a custom Adapter inherits from PagerAdapter for controlling the ViewPager’s work, ViewPagerAdapter.java

package pete.apps.study.droid05;

import android.content.Context;
import android.os.Parcelable;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;

public class ViewPagerAdapter extends PagerAdapter {

    private static String[] titles = new String[] {
        "Girl",
        "Dog",
        "Cat"
    };

    private static int[] images = new int[] {
        R.drawable.girl,
        R.drawable.dog,
        R.drawable.cat
    };

    private final Context context;

    public ViewPagerAdapter(Context context) {
        this.context = context;
    }

    @Override
    public String getPageTitle(int position) {
        return titles[position];
    }

    @Override
    public int getCount() {
        return titles.length;
    }

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        ImageView view = new ImageView(this.context);
        view.setImageResource(images[position]);
        ((ViewPager) container).addView(view, 0);
        return view;
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        ((ViewPager) container).removeView((ImageView) object);
    }

    @Override
    public boolean isViewFromObject(View view, Object object) {
        return view.equals(object);
    }

}

– Finally the MainScreen.java

ackage pete.apps.study.droid05;

import android.app.Activity;
import android.os.Bundle;
import android.support.v4.view.ViewPager;
import android.view.Window;
import android.view.WindowManager;
import com.viewpagerindicator.TitlePageIndicator;

public class MainScreen extends Activity
{
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

        setContentView(R.layout.main);

        ViewPagerAdapter adapter = new ViewPagerAdapter(this);
        ViewPager pager = (ViewPager) findViewById(R.id.viewpager);
        TitlePageIndicator title = (TitlePageIndicator) findViewById(R.id.titles);
        pager.setAdapter(adapter);
        title.setViewPager(pager);
    }
}

4. Execute the final
– Let’s build and run the code to see the results

$ ant clean debug install

C – Get source

– Get full source code at: Browse Source

 

Well, enjoy and create your amazing application !

Cheers,

Pete Houston

 

Build ViewPagerIndicator with Ant

December 26, 2012 Leave a comment

ViewPagerIndicator is one of the great libraries that helps to indicate the page status of when using ViewPager.

If you want to know more about it, visit the developers’ homepage: http://viewpagerindicator.com/

By default, it’s set to build with Maven, not Ant. So in order to build with Ant, you should do the following steps:

1. Download the package and extract it, you can click here to download,

or you can checkout it source code from developers’  branch: https://github.com/JakeWharton/Android-ViewPagerIndicator

Then name the directory, I named it: ~/ViewPagerIndicator

2. Navigate to this directory and start to create the project settings and build.xml for Ant build:

$ cd ViewPagerIndicator

$ android update project -p library/
Updated local.properties
No project name specified, using project folder name 'library'.
If you wish to change it, edit the first line of build.xml.
Added file ~/ViewPagerIndicator/library/build.xml
Added file ~/ViewPagerIndicator/library/proguard-project.txt

3. Build the sample source code and run it!

$ android update project -p sample/
Updated local.properties
No project name specified, using Activity name 'ListSamples'.
If you wish to change it, edit the first line of build.xml.
Added file ~/ViewPagerIndicator/sample/build.xml
Added file ~/ViewPagerIndicator/sample/proguard-project.txt

$ cd sample

$ ant clean

$ ant debug install

Now open your device and run the sample to enjoy the features that the library brings.

@p/s: Thanks Jake Wharton for this cool library and his support.

 

Cheers,
Pete Houston

Guide to create, build and sign Android applications (using command)

September 5, 2012 3 comments

Today, I’d like to take you to a tour guide of how-to create, build and sign Android applications.

I – Setup the environment

– For building an Android app, you will need the help of Ant, for example, I use Apache Ant 1.8.4 for this tutorial, which is the current version at the time of this post written.

Download this package: http://apache.cs.utah.edu//ant/binaries/apache-ant-1.8.4-bin.zip

Extract it to [C:\Program Files\Ant]

It’s for Windows users, if you’re on Linux or Mac, just get and install it from Software Package Manager, it will install automatically for you, and you don’t need to do the following step of adding command to environment.

– For Windows users, now you need to add some commands to the PATH.

Open [Control Panel > System > tab Advanced -> button Environment Variables],

On the group [System variables], find the [Path] and add the following path to it:

+) path to JDK binary: for example, [C:\Program Files\Java\jdk1.6.0_18\bin]

+) path to Android Tools: for example, [C:\Program Files\Android\android-sdk\tools]

+) path to Android Platform-Tools: for example, [C:\Program Files\Android\android-sdk\platform-tools]

+) path to Apache Ant binary: for example, [C:\Program Files\Ant\bin]

Now, the value of my [Path] variable now is like:

C:\Perl\site\bin;C:\Perl\bin;%SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem;%SYSTEMROOT%\System32\WindowsPowerShell\v1.0\;C:\Program Files\Android\android-sdk\platform-tools;C:\Program Files\Microsoft SQL Server\100\Tools\Binn\;C:\Program Files\Microsoft SQL Server\100\DTS\Binn\;C:\Program Files\Android\android-sdk\platform-tools;C:\Program Files\Android\android-sdk\tools;C:\Program Files\Ant\bin;C:\Program Files\Java\jdk1.6.0_18\bin;

Yours will be similar to mine.

Environment Variables

Environment Variables

II. Create, Build and Sign

1. Now, let’s go to create one project from command-line.

First, check for which Android platform SDK has been installed on your computer.

> android list targets

The output will list all platforms installed, for example:

Available Android targets:
----------
id: 1 or "android-15"
     Name: Android 4.0.3
     Type: Platform
     API level: 15
     Revision: 3
     Skins: HVGA, QVGA, WQVGA400, WQVGA432, WSVGA, WVGA800 (default), WVGA854, W
XGA720, WXGA800
     ABIs : no ABIs.

Your result might have more than mine.

It also means that I can create an Android project for platform “android-15” or id = 1. This value is required to create project.
Ok, I’m creating a sample project:

> android create project --target android-15 --name PeteApp --path ./PeteAppProject --activity MainActivity --package pete.apps.samples.peteapp

[–target] : is the target platform that your project will be running on
[–name] : indicate the name of your application, the APK created will have this name. Anyway, it’s optional, if you don’t specify this parameter, then the either project name or your first activity name will be chosen to be the name of your application. (you might wanna test this!)
[–path] : specify the directory of the project, it will use the existing directory, otherwise, create new.
[–activity] : the first screen or the entrance of your Droid app, it will be registered into [AndroidManifest.xml].
[–package] : your default package name.

That’s all, not that hard right?
The output would be…

Created project directory: E:\AndroidSamples\PeteAppProject
Created directory E:\AndroidSamples\PeteAppProject\src\pete\apps\samples\peteapp

Added file E:\AndroidSamples\PeteAppProject\src\pete\apps\samples\peteapp\MainAc
tivity.java
Created directory E:\AndroidSamples\PeteAppProject\res
Created directory E:\AndroidSamples\PeteAppProject\bin
Created directory E:\AndroidSamples\PeteAppProject\libs
Created directory E:\AndroidSamples\PeteAppProject\res\values
Added file E:\AndroidSamples\PeteAppProject\res\values\strings.xml
Created directory E:\AndroidSamples\PeteAppProject\res\layout
Added file E:\AndroidSamples\PeteAppProject\res\layout\main.xml
Created directory E:\AndroidSamples\PeteAppProject\res\drawable-hdpi
Created directory E:\AndroidSamples\PeteAppProject\res\drawable-mdpi
Created directory E:\AndroidSamples\PeteAppProject\res\drawable-ldpi
Added file E:\AndroidSamples\PeteAppProject\AndroidManifest.xml
Added file E:\AndroidSamples\PeteAppProject\build.xml
Added file E:\AndroidSamples\PeteAppProject\proguard-project.txt

Just add source files or whatever stuffs you need…that’s done for the creation.

2. Build it!!!
– There are two build mode in development, [Debug] and [Release]
– You can use these command to build depending on your mode.

> ant debug
> ant release

The [bin] directory will be created including your [***-debug-unaligned.apk] or [***-release-unaligned.apk].
– If you ever change anything in [res] (resources) directory, you should remove all stuffs in [bin] and [gen] directory, otherwise, it might cause bug in run-time, due to “fail to load resources”. This is one of very common mistake, so you should be aware of this. However, if you don’t want to work handy, you can use this robo-command:

> ant clean

– In order to install your application, there are many ways, but I show you two common methods:
+) use [Ant] for work, this depend on your mode:

> ant debug install
> ant release install

+) use [ADB], navigate to your [bin] directory:

> adb install AppName.apk

3. Release It!!!
– Got your APK work now, but it’s not ready for distribution on Market/Google Play. What you need to do next is to sign and align your release APK. The step is: create keystore > sign APK with key > align final package.

+) Create Key:
Look at my command:

> keytool -genkey -v -keystore peteapp.keystore -alias peteapp -keyalg RSA -keysize 2048 -validity 10000

Here the output

Enter keystore password:
Re-enter new password:
What is your first and last name?
  [Unknown]:  Pete Houston
What is the name of your organizational unit?
  [Unknown]:  Nowhere
What is the name of your organization?
  [Unknown]:  Noname
What is the name of your City or Locality?
  [Unknown]:  Seoul
What is the name of your State or Province?
  [Unknown]:  Kangnam
What is the two-letter country code for this unit?
  [Unknown]:  KR
Is CN=Pete Houston, OU=Nowhere, O=Noname, L=Seoul, ST=Kangnam, C=KR correct?
  [no]:  yes

Generating 2,048 bit RSA key pair and self-signed certificate (SHA1withRSA) with a validity of 10,000 days
        for: CN=Pete Houston, OU=Nowhere, O=Noname, L=Seoul, ST=Kangnam, C=KR
Enter key password for <peteapp>
        (RETURN if same as keystore password):
[Storing peteapp.keystore]

For details, please visit this link: Obtain a key

+) Sign the APK:
– Remember, you must create the APK in [Release] mode before doing this.

> jarsigner -verbose -sigalg MD5withRSA -digestal
g SHA1 -keystore peteapp.keystore bin\PeteApp-release-unsigned.apk peteapp

The result:

Enter Passphrase for keystore:
   adding: META-INF/MANIFEST.MF
   adding: META-INF/PETEAPP.SF
   adding: META-INF/PETEAPP.RSA
  signing: res/layout/main.xml
  signing: AndroidManifest.xml
  signing: resources.arsc
  signing: res/drawable-hdpi/ic_launcher.png
  signing: res/drawable-ldpi/ic_launcher.png
  signing: res/drawable-mdpi/ic_launcher.png
  signing: classes.dex

– Now verify whether the signing process was OK.

> jarsigner -verify -verbose -certs bin\PeteApp-release-unsigned.apk

[-certs] : will display the validation of each and every signed file.
[-verbose] : to display the output, there you can check.

+) Align the final:

> zipalign -v 4 bin\PeteApp-release-unsigned.apk PeteApp.apk

The final signed and aligned package [PeteApp.apk] will be created under the main directory of the project.

Now you can use this APK to distribute on Market/Google Play 🙂

III – References
If you do a search over Internet, there are some good articles about this work, I also do refer from them as well. IF you feel any hard part, try to refer to them all and get the idea how it works.

Android Developers – Building and Running from Command Line

Android Developers – Sign Your Application

Android Engineer – Using Ant to Automate Building Android 

 

IV – Final Words

Well, enjoy and have fun!

 

Cheers,

Pete Houston

Categories: Tutorials Tags: , , , , , , , , ,

Create a Service that does a schedule task

July 7, 2012 16 comments

Sometimes you need to do a schedule task for a fixed rate (repeatedly), like [check for emails], [check for battery], [update new Facebook status], etc…

The tip here is to use Service and implement a Timer running a TimerTask for an interval.

My sample here is that I like to get Date and Time in every 10 seconds and display a Toast notification to users.

Here how it looks:

Sample Schedule Task

Sample Schedule Task

So I create my own service called TimeService:

public class TimeService extends Service {
	// constant
	public static final long NOTIFY_INTERVAL = 10 * 1000; // 10 seconds

	// run on another Thread to avoid crash
	private Handler mHandler = new Handler();
	// timer handling
	private Timer mTimer = null;

	@Override
	public IBinder onBind(Intent intent) {
		return null;
	}

	@Override
	public void onCreate() {
		// cancel if already existed
		if(mTimer != null) {
			mTimer.cancel();
		} else {
			// recreate new
			mTimer = new Timer();
		}
		// schedule task
		mTimer.scheduleAtFixedRate(new TimeDisplayTimerTask(), 0, NOTIFY_INTERVAL);
	}

	class TimeDisplayTimerTask extends TimerTask {

		@Override
		public void run() {
			// run on another thread
			mHandler.post(new Runnable() {

				@Override
				public void run() {
					// display toast
					Toast.makeText(getApplicationContext(), getDateTime(),
							Toast.LENGTH_SHORT).show();
				}

			});
		}

		private String getDateTime() {
			// get date time in custom format
			SimpleDateFormat sdf = new SimpleDateFormat("[yyyy/MM/dd - HH:mm:ss]");
			return sdf.format(new Date());
		}

	}

It’s easy to understand, isn’t it?

Next is to register the TimerService to AndroidManifest for identification.

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/title_activity_main" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <service android:name=".TimeService"/>
    </application>

Our last step is to give a call for starting our service when activity executes.

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

        startService(new Intent(this, TimeService.class));
    }

Finally, just run on the phone and see the result.
The implementation is pretty straightforward and simple. You can freely use this way to create some schedule tasks for your applications.

Cheers,
Pete Houston

Categories: Tutorials Tags: , ,

New Cache for Better Memory Performance


Hanging around and reading Android articles, and suddenly I want to check out new information on Android Training Page.

As a developer having lots of interest in Android Performance & Optimization, I check this section first: Cache with Bitmaps.

Got a note from the page:

Note: In the past, a popular memory cache implementation was a SoftReference or WeakReference bitmap cache, however this is not recommended. Starting from Android 2.3 (API Level 9) the garbage collector is more aggressive with collecting soft/weak references which makes them fairly ineffective. In addition, prior to Android 3.0 (API Level 11), the backing data of a bitmap was stored in native memory which is not released in a predictable manner, potentially causing an application to briefly exceed its memory limits and crash.

Just like something light up in my head, this explains why sometimes some of my apps crash in memory limitation strangely before.

The two new class introduced to work around with Bitmap Caching is: LruCache and DiskLruCache.

So if you got any problem with bitmap memory, this could be a hint to your optimizing solution for your Android apps.

 

Cheers,

Pete Houston

Categories: Tutorials Tags: , ,

Android XML Adventure – Parsing HTML using JSoup

February 4, 2012 22 comments

Article Series: Android XML Adventure

Author: Pete Houston (aka. `xjaphx`)

TABLE OF CONTENTS

  1. What is the “Thing” called XML?
  2. Parsing XML Data w/ SAXParser
  3. Parsing XML Data w/ DOMParser
  4. Parsing XML Data w/ XMLPullParser
  5. Create & Write XML Data
  6. Compare: XML Parsers
  7. Parsing XML using XPath
  8. Parsing HTML using HtmlCleaner
  9. Parsing HTML using JSoup
  10. Sample Project 1: RSS Parser – using SAXParser
  11. Sample Project 1: RSS Parser – using DOM Parser
  12. Sample Project 1: RSS Parser – using XMLPullParser
  13. Sample Project 2: HTML Parser – using HtmlCleaner
  14. Sample Project 2: HTML Parser – using JSoup
  15. Finalization on the “Thing” called XML!

=========================================

Another library used common for parsing HTML is JSoup.

Unlike HtmlCleaner, JSoup uses the concept of attributes as a selector to identify each node in HTML tree.

I suggest you should learn the basics syntax of JSoup selector before continue, http://jsoup.org/cookbook/extracting-data/selector-syntax

Well, we will do the same thing as previous article, we get the blog statistics using JSoup.

The syntax is like this: ” div#blog-stats ul li

Literally, it means: select the node <li> inside node <ul> , which has parent is a <div> having ID value is “blog-stats“.

Download the libary JSoup and add it as “External JARs”.

Head straight to the source code to get our desire value:

package pete.android.study;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

public class JSoupStudyActivity extends Activity {

	// blog url
	static final String BLOG_URL = "https://xjaphx.wordpress.com/";

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

        // process
        try {
        	((TextView)findViewById(R.id.tv)).setText(getBlogStats());
        } catch (Exception ex) {
        	((TextView)findViewById(R.id.tv)).setText("Error");
        }
    }

    protected String getBlogStats() throws Exception {
    	String result = "";
    	// get html document structure
    	Document document = Jsoup.connect(BLOG_URL).get();
    	// selector query
    	Elements nodeBlogStats = document.select("div#blog-stats ul li");
    	// check results
    	if(nodeBlogStats.size() > 0) {
    		// get value
    		result = nodeBlogStats.get(0).text();
    	}

    	// return
    	return result;
    }
}

Remember to add INTERNET permission. Here the result on my Galaxy S II phone, which is a little chocky-cocky:

JSoup Sample

JSoup Sample

Not so much different from XPath, is it?

Cheers,

Pete Houston

Categories: Tutorials Tags: , , , , , ,

Android XML Adventure – Parsing HTML using HtmlCleaner

February 4, 2012 26 comments

Article Series: Android XML Adventure

Author: Pete Houston (aka. `xjaphx`)

TABLE OF CONTENTS

  1. What is the “Thing” called XML?
  2. Parsing XML Data w/ SAXParser
  3. Parsing XML Data w/ DOMParser
  4. Parsing XML Data w/ XMLPullParser
  5. Create & Write XML Data
  6. Compare: XML Parsers
  7. Parsing XML using XPath
  8. Parsing HTML using HtmlCleaner
  9. Parsing HTML using JSoup
  10. Sample Project 1: RSS Parser – using SAXParser
  11. Sample Project 1: RSS Parser – using DOM Parser
  12. Sample Project 1: RSS Parser – using XMLPullParser
  13. Sample Project 2: HTML Parser – using HtmlCleaner
  14. Sample Project 2: HTML Parser – using JSoup
  15. Finalization on the “Thing” called XML!

=========================================

After a long time, now I’d like to come back to the series, sorry guys for make you all waiting.

In this article, I will give a simple guide on how to use HtmlCleaner to parse HTML data in XPath format.

You might get to know what XPath is already and learned how to use XPath library on Android system.

This time, we will use a XPath to query the value we desire to have from an HTML page not XML file, interesting, isn’t it?

The HTML Page target is my blog: https://xjaphx.wordpress.com/

The data will be desired to parse is the “Statistics“, number of Views on my blog, which is on the bottom-right side of the blog. The current number is: 80,303 views.

The XPath for this is: “//div[@id=’blog-stats’]/ul/li

First, get the HtmlCleaner library and set it up, get it from here: http://htmlcleaner.sourceforge.net/

Open your Eclipse and create new project, then right click to the project on the left pane, select Properties.

HtmlCleaner Setup

HtmlCleaner Setup

Ok, on tab Libraries, click button “Add External JARs” on the right side, a dialog to select JAR files open up, select the HtmlCleaner library, then click button Open. It’s done for setting up the library.

Next is the layout of application, I use the default one, only one TextView, well, just enough to confirm value.

Let’s get straight to the source code 🙂

package pete.android.study;

import java.net.URL;

import org.htmlcleaner.CleanerProperties;
import org.htmlcleaner.HtmlCleaner;
import org.htmlcleaner.TagNode;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

public class HtmlCleanerStudyActivity extends Activity {

	// HTML page
	static final String BLOG_URL = "https://xjaphx.wordpress.com/";
	// XPath query
	static final String XPATH_STATS = "//div[@id='blog-stats']/ul/li";

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

        // decide output
        String value = "";
        try {
        	value = getBlogStats();
        	((TextView)findViewById(R.id.tv)).setText(value);
        } catch(Exception ex) {
        	((TextView)findViewById(R.id.tv)).setText("Error");
        }
    }

    /*
     * get blog statistics
     */
    public String getBlogStats() throws Exception {
    	String stats = "";

    	// config cleaner properties
    	HtmlCleaner htmlCleaner = new HtmlCleaner();
    	CleanerProperties props = htmlCleaner.getProperties();
    	props.setAllowHtmlInsideAttributes(false);
    	props.setAllowMultiWordAttributes(true);
    	props.setRecognizeUnicodeChars(true);
    	props.setOmitComments(true);

    	// create URL object
    	URL url = new URL(BLOG_URL);
    	// get HTML page root node
    	TagNode root = htmlCleaner.clean(url);

    	// query XPath
    	Object[] statsNode = root.evaluateXPath(XPATH_STATS);
    	// process data if found any node
    	if(statsNode.length > 0) {
    		// I already know there's only one node, so pick index at 0.
    		TagNode resultNode = (TagNode)statsNode[0];
    		// get text data from HTML node
    		stats = resultNode.getText().toString();
    	}

    	// return value
    	return stats;
    }
}

Also, remember to set INTERNET permission as well on AndroidManifest.xml

Run it, and get the result:

HtmlCleaner Output

HtmlCleaner Output

It’s the output from my phone: Galaxy S II.

This library is simple and pretty fast and I’d like to use it. If you know any other better libraries, please let me know, I’d like to get it too.

In case you have some trouble, you can get this full source code: Get HtmlCleaner Sample Project

Cheers,

Pete Houston

Categories: Tutorials Tags: , , , ,