Posts Tagged ‘Android’

The Joys of Screen Scraping

Knucklehead Up and Running Again



For about a week there my MMA fighter app for Android, Knucklehead, has been out of commission. The reason is that the site that I scrape for data, Sherdog was completely redesigned. I needed to rework a lot of my PHP-based screen scraping code to make it work. My PHP is rusty, but fortunately, my regular expression chops are always sharp. In any case, it’s back to working order now.

Maybe with a little luck I can get people to re-rate those 1-star ratings I got while it was down. If not, perhaps I can guilt people into giving me good ratings by saying that it’s my newborn son’s fault I didn’t get to it sooner. I mean, really, are you going to give the father of this child a hard time? Don’t be so heartless. :)

Screen Scraping Tips


As we all know, screen scraping is pretty much the most volatile way to supply your apps with data. While no amount of planning can permanently future-proof your screen scraper, there’s some things you can do to make it easier.

  • Define a data model for what you are scraping. What made my project relatively easy to get working again was that I had a clearly defined data model shared by both the backend and frontend. In my case, this is a LAMP stack and distributed Android app respectively. Now my users don’t need to download a new version of my app in order to get the fix. It just works now.
  • Code the scraper on a backend proxy, not in the app itself. That way, when your scraper inevitably gets broken at some point (after a year in my case), you only need to change the code in one place. This goes hand-in-hand with defining a data model.
  • Keep it simple stupid. Don’t over-architect a screen scraper. Most data processing code will change over time, but a screen scraper may need a total rewrite at some point. Put all your software engineering skills into controlling what leaves the scraper, but play it pretty loose with what the scraper is going to be processing.
  • Using JSON? You better be using jsonlint.com too. jsonlint.com can save you a lot of time and aggravation when it comes to creating and processing your scraped data. Not only does it validate your JSON, but it will also pretty print it so it’s easy to read through yourself.

That’s just a couple things that made fixing my scraper a lot less painful. You guys out there have any tips? I’d love to hear them. All things being equal, I hope I never have to screen scrape for data ever again. But since that’s pretty unlikely, it’s good to be prepared for the inevitable obstacles that scraping will present.

3D, Sockets, and Native Android with Appcelerator Titanium

Yeah, yet another cross-post from the Appcelerator Developer blog. This was a fun one, though, where I got to show off some really cool features and functionality of the Titanium platform. There’s a lot covered so it’s stretched over a 3 part series. I’ve brought them all together here for your viewing pleasure. The original blog post links included with each video contain links for all the source code and references associated with each video.

Here’s the 10 second summary of each part:

  1. Create a native Android module to determine a device’s physical orientation as azimuth, pitch, and roll
  2. Use the above data to animate and render a 3D model using a Titanium WebView and
  3. Represent this 3D model on multiple remote client devices simultaneously using high volume, realtime network communication via Titanium Sockets

Part 1 – Native Android Module

>>> Original blog post


Part 2 – 3D With Three.js

>>> Original blog post


Part 3 – Sockets

>>> Original blog post

Android Intents in Appcelerator

Link To Full Blog Post


Here We Go Again


OK, well I just did a post on how to use Android Intent Filters with Appcelerator, so why not the other side of the coin. This time you’ll learn how you can send Intents instead of receiving them. With this powerful native functionality you’ll be able to leverage existing apps on your Android device to do some of your heavy lifting, like sharing images, sending text, and a whole bunch of other things.

Android Intent Filters in Appcelerator

Link To Full Blog Post


It Starts…


Here’s just a cross post of my first tutorial on the Appcelerator Developer Blog. It details how you can use Android Intent Filters to make your Appcelerator apps receive Intents from other Android applications. For example, I’m sure if you are an Android user you are familiar with the SEND Intent list:

Intent List

With this blog post I’ll show you how you can add your app to that list. It’s a great example of how Appcelerator still leverages powerful native functionality, both visual and non-visual, while it provides a cross platform solution.

Waiting for Android: UrlJsonAsyncTask

When creating my MMA fighter search app for Android, Knuckle Head, I created a class that I have reused a few times since. Its called UrlJsonAsyncTask and the code necessary to use it is available in my . The following excerpt describes the problem it was built to solve:

I can’t even count how many times I’ve had to load a ProgressDialog in Android, query JSON from a remote URL, and then return control back to the app once the query has completed. It’s an incredibly common control flow, and one I’m sick of doing over and over again. I’m sure I’m not alone.

In effort to keep this a DRY situation, the class in my collection of Android helpers, , is dedicated to the aforementioned task. It reduces what can be an 80+ line of code endeavor, per task, down to about 15 or less.

For the rest of the article, head over to the full article at BuildMobile.com and check it out. The full article includes a full explanation of the code, a with full source, and even a downloadable Android app for testing the functionality yourself.

A Whole Mess of Android Helpers

Overview


In my work on my MMA fighter Android app Knuckle Head I used a lot of Android functionality that I’m sure I’ll use again. Things like JSON processing, asynchronous tasks with ProgressDialogs, and single instance Toasts are all things that will inevitably show up in future work. Because I’m just so generous, I decided to refactor them out of the Knuckle Head specific code and turn them into a Java package anyone could use.

* Clone or download

 

The Classes


Its a small collection so far, but sure to grow very quickly. Here’s a list of the classes included so far:

  • – A collection of JSON handling functions. Includes Retrieving JSON from a remote URL.
  • – A generic key/value pait class. Useful for populating Android Spinners.
  • – A collection of static classes for operations I don’t have a better home for.
  • – I hate how Toasts in Android are shown sequentially. To prevent this I operate on a single instance of a Toast throughout my apps.
  • – A class that utilizes ToastSingleton.java and delivers Toasts with convenient static functions.
  • – This is a custom AsyncTask for a very common Android problem. I very often need to retrieve JSON from a remote URL, display a ProgressDialog while this occurs, operate on the data when it is returned, and then close the ProgressDialog. With this class that work is reduced down to just a few lines of code.
 

UrlJsonAsyncTask Example


If you had only have time for a quick look, be sure to check . Using this class in side my Activity code reduced the line count drastically. Since I was lazy about documentation for any of this, here’s an example to reward my blog reader’s. This is straight from Knuckle Head code. You’ll notice a few other classes mentioned above are also included.

UrlJsonAsyncTask is not abstract like AsyncTask, most of the functionality has been implemented. You only need to implement onPostExecute(JSONObject) if you want to do something with the returned JSON. In order for this to work, your JSON needs to return an object formatted like this:

{
    "success":true|false,
    "info":"error or warning message from server",
    "data": {}
}
  • success is a boolean indication from your JSON source whether or not the request was successful
  • info on error or warning, will contain an app user friendly message that can be delivered via Toast
  • data This is the actual JSON object or array that you will operate on given a successful request
 

And this is how you would define your own UrlJsonAsyncTask. In this case I am querying my server to get a list of fighter, or the profile of one particular fighter. In either scenario, as stated in the JSON description above, the “data” attribute of my JSON is what I will pass to the target intent.

private class FighterSearchTask extends UrlJsonAsyncTask {
    public FighterSearchTask(Context context) {
        super(context);
    }
 
    @Override
    protected void onPostExecute(JSONObject json) {
        try {
            this.validateJson(json); // throws IOException, JSONException
 
            // These 4 lines represent the actual post execute logic
            Class> intentClass = json.getString("info").equals("list") ? FighterListActivity.class : FighterTabActivity.class;
            Intent intent = new Intent(context, intentClass);
            intent.putExtra("json", json.getString("data").toString());
            startActivity(intent);
        } catch (IOException e) {
            // IOExceptions are custom and return JSON "info" in getMessage()
            Toaster.toast(this.context, e.getMessage());
        } catch (JSONException e) {
            // Lazy.Ex.getStackTrace(Exception) is just a simple one liner for turning 
            // a stack trace into a String.
            Log.e("YourTagName", Lazy.Ex.getStackTrace(e));
 
            // JSONExceptions here are generally because your JSON is not formatted as 
            // per the description in the comments above. We don't want to show these 
            // errors to the user, so we give them a pre-defined error message to let 
            // them know something went wrong.
            Toaster.toast(context, this.getMessageError());
        } finally { 
            super.onPostExecute(json); // Must be called to close the ProgressDialog
        }
    }
}

After you have created your subclass of UrlJsonAsyncTask, you can execute these following few lines of code anywhere to fire your task and have a ProgressDialog pop up until it either finishes successfully or or returns an error/warning message. There’s tons of setters to customize your task. Check them out in the .

FighterSearchTask task = new FighterSearchTask(SearchActivity.this);
task.setMessageLoading("Searching for fighters...");
task.setConnectionParams(2000, 5000, 3); // connection timeout(ms), read timeout(ms), number of retries
task.execute(url);

And voila, you got JSON from a remote URL with a ProgressDialog assuring your users that the data is in fact loading. All of this is non-blocking so you are able to continue other operations or update the UI if necessary.

Summary


So yeah, it’s just another collection of a developer’s reusable tools for getting stuff done, this time for Android. If you do happen to peruse, or use, the code, let me know what you think. Suggestions,criticisms, and of course contributions are more than welcome.

Knuckle Head: My MMA Fighter App for Android

Get the App


* Click here to download “Knuckle Head” on the Android Market!

Overview


Knuckle Head is an app for the true Mixed Martial Arts fan. It allows you to search a database to find details on any fighter in the world, not just the UFC. In just a few touches you can search by name, nickname, or weight class to find every detail about your favorite fighters. This is not just another MMA news app. Inside you’ll find fighter images, detailed fight records, vital statistics, and other MMA analysis.

Oh, and I love feedback, so tell me what you want next!

Screenshots


In Case You Were Interested…


I’ll have some technical blog posts regarding this app up very soon. There’ll be lots of native Android development goodies to be gleaned. In addition I’m likely gonna post up some Android/Java convenience classes I’ve been using for various tasks like JSON handling, AdMob, ProgressDialogs, and more to my . Stay tuned.

Handling Global Configuration in Android

The Problem

You have configuration variables and data that you want to share globally in your Android app. You want all Activities to be able to access and edit the same instance of application specific data.

Generic Solution

You could create a Configuration class loaded with static members or as a Singleton. Now you’ve got a shared, single instance of your configuration that can be accessed anywhere in your application. But there are 2 minor drawbacks to this method in the context of Android development.

  1. You now have to initialize your configuration in a separate class, in this case, your startup Activity.
  2. You’ll need to carry this new Configuration class around in all your projects.

Neither of these problems are critical, but let’s see if we can do better.

Android Solution

In Android it is possible to extend the Application class in order to store additional application specific information… like say configuration data. These additional members are then accessible in any Activity via the getApplicationContext() method.

The first step in this process is extending your app’s Application object. Android gives your app a generic Application object by default, so you may have never even had to look at this class directly. But as you’ll see below, its pretty simple to extend.

SampleApplication.java

public class SampleApplication extends Application {
    private String mStringValue;
 
    @Override
    public void onCreate() {
        // Here you could pull values from a config file in res/raw or somewhere else
        // but for simplicity's sake, we'll just hardcode values
        mStringValue = "SavageLook.com";
        super.onCreate();
    }
 
    public String getStringValue() {
        return mStringValue;
    }
 
    public void setStringValue(String value) {
        mStringValue = value;
    }
}

As you can see above, extending the Application class as SampleApplication is quite simple. You add class members for each bit of configuration data you would like to share throughout your application. In this example, we are simply saving a String value (mStringValue) that can then be accessed and modified in any Activity in SampleApplication.

After you’ve added your members and any necessary getters/setters, you need to override the onCreate() method. In the onCreate() method you can then initialize your class members with your configuration data. You can do this any way you want. To keep the example simple, I hardcoded the configuration value (mStringValue), but I commonly store configuration data in JSON files in res/raw and load them into my extended Application object. I won’t get into those details, though, as that will likely be a whole other blog post. Make sure you call super.onCreate() when you are finished.

NOTE: It’s not necessary to initialize your members in the onCreate(). For application-wide configuration data you would likely always do it in onCreate(), but you are technically free to manipulate the extended Application object anywhere in your app code.

AndroidManifest.xml

 version="1.0" encoding="utf-8"?>
 xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.yourdomain"
      android:versionCode="1"
      android:versionName="1.0">
 
    
 
     
        android:icon="@drawable/icon" 
        android:label="@string/app_name"
        android:name=".SampleApplication">
         android:name=".SampleActivity">
            >
                 android:name="android.intent.action.MAIN" />
                 android:name="android.intent.category.LAUNCHER" />
            >
        >
    >
>

The final modification to make our Android app use the new SampleApplication class is setting it in the element of the AndroidManifest.xml file. The only change we make to AndroidManifest.xml is adding the android:name attribute to the element. Just add this attribute and set it equal to the name of your extended Application object, in this case SampleApplication.

OK, so now your app is using your new SampleApplication class. How do we access the stored data in its members? See the basic usage below.

Sample usage in any Activity

public class SampleActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
 
        SampleApplication sampleApp = (SampleApplication)getApplicationContext();
        String localStr = sampleApp.getStringValue();    
        // perform operations on localStr
        sampleApp.setStringValue(localStr);
 
        // The rest of your Activity code...
    }
}

All you have to do is call getApplicationContext() and cast it to the type of your new Application object (SampleApplication). The resulting SampleApplication object can now be used the get/set any of the members you defined for it in SampleApplication.java.

Summary

Now you have a solid, Android native way to share data globally in your app code. While I’m a big fan of portable solutions, I feel this Android specific one is worth to have a clear distinction between the onCreate() of my Application versus my Activities. Hopefully this walkthrough was clear because this is something you will likely do very frequently when developing Android apps.

One final note. I can already envision some lazy developers’ minds churning, “I can use this instead of Intent extras!”… Don’t! Intent extras have a specific interaction context which is important not only to functionality, but also to readability of your code. Don’t undo this by just feeding them into the global Application object. Extending your Application object is a complement to Intent extras, not a replacement.

Android Quick Tip: EditText with DONE Button That Closes the Keyboard

Android Quick Tip

Close the keyboard when you click ‘DONE’… seems like a simple task, right? Unfortunately, clicking ‘DONE’ or the ‘RETURN’ button in even a single line Android EditText will not drop focus and close the soft keyboard. In most cases it will just generate a new line of text. So what do you have to do if you want to close the soft keyboard by clicking ‘DONE’?

First you need to set the android:imeOptions attribute equal to “actionDone” for your target EditText as seen below. That will change your ‘RETURN’ button in your EditText’s soft keyboard to a ‘DONE’ button.

* example_edittext.xml

 
    android:id="@+id/edittext_done"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:hint="Enter some text"
    android:imeOptions="actionDone"
    />

Now we need to create a custom OnEditorActionListener for the target EditText that will recognize when the ‘DONE’ button has been clicked. In it we override the onEditorAction() method, get an instance of the InputMethodManager, and use it to close the soft keyboard. Here’s the code for the custom OnEditorActionListener class:

* DoneOnEditorActionListener.java

class DoneOnEditorActionListener implements OnEditorActionListener {
    @Override
    public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
        if (actionId == EditorInfo.IME_ACTION_DONE) {
            InputMethodManager imm = (InputMethodManager)v.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
            imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
            return true;   
        }
        return false;
    }
}

Now go to the onCreate() method of the Activity that contains the target EditText. We’ll call it SampleActivity here. In here you will assign the new DoneOnEditorActionListener to the target EditText via the setOnEditorActionListener() method.

* SampleActivity.java

public class SampleActivity extends Activity {      
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.sample_activity_layout); // sample_activity_layout contains our target EditText, target_edittext
 
        EditText targetEditText = (EditText)findViewById(R.id.target_edittext); 
        targetEditText.setOnEditorActionListener(new DoneOnEditorActionListener());
 
        // The rest of the onCreate() code
   }
}

And there you go, your target EditText field will now close the soft keyboard whenever you click the ‘DONE’ button. Very handy and not too difficult. Enjoy.

Android Quick Tip: Tiling a Background Image

Android Quick Tip

Often times you’ll want to tile, or repeat, a small image as the background of an Android view or layout. This is just like using the ‘background-image’ and ‘background-repeat’ CSS options, and almost as easy. First and most importantly, you’ll need an image to tile. If you don’t have one of your own, use the one below (right click and “Save Image”).

carbon_fibre.gif

Carbon Fiber tile

Now, in your project’s res/drawable path, create a file named tile_background.xml. Fill the file with the following XML:

tile_background.xml

 version="1.0" encoding="UTF-8" ?>
 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:src="@drawable/carbon_fibre" 
    android:tileMode="repeat" 
    />

Now all you have to do is set the android:background attribute of your target view or layout to the tile_background.xml drawable id, like so:

sample_layout.xml

 version="1.0" encoding="utf-8"?>
 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@drawable/tile_background"
    >
>

And if sample_layout.xml was the assigned content view for your main activity, you would see this when you started your app:

tiled