Category Archives: Programming

BundleButler: Simplifying arguments and savedInstanceState

To make proper use of both Fragment arguments and saved instance state in Android, I found myself frequently writing a great deal of the same boilerplate code. Most of that code looked like this:

public class EditEntryFragment extends Fragment {
    private Entry entry;
    private String title;
    private boolean hasAgreedToTerms = false;
    public static EditEntryFragment createInstance(Entry currentEntry, String title) {
        EditEntryFragment fragment = new EntryEditFragment();
        Bundle args = new Bundle();
        args.putParcelable("entry", currentEntry);
        args.putString("title", title);
        fragment.setArguments(args);
        return fragment;
    }
 
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Bundle args = getArguments();
        if(args != null) {
            entry = (Entry)args.getParcelable("entry");
            title = args.getString(title);
        }
        if(savedInstanceState != null) {
            if(savedInstanceState.containsKey("entry") {
                entry = (Entry)savedInstanceState.getParcelable("entry");
            }
            hasAgreedToTerms = savedInstanceState.getBoolean("hasAgreedToTerms", hasAgreedToTerms);
        }
        // use saved entry to populate form fields / load images, etc.
    }
 
    public void onSaveInstanceState(Bundle state) {
        super.onSaveInstanceState(state);
        state.putParcelable("entry", entry);
        state.putBoolean("hasAgreedToTerms", hasAgreedToTerms);
    }
}

Of course bundling all state into a Parcelable or Bundle like this reduces said boilerplate as we’re not keeping track of all form fields or state individually, but we still have to write code to:

  • Check that arguments and state have been provided (null checks)
  • Check that keys we care about exist
  • Decide when to use the saved state of a field over the argument over the default value
  • Bundle each argument in createInstance
  • Store each field into state

Each of these actions is fairly trivial, but leads to a lot of code that is easy to lose track of or get wrong.

Bundle Butler generates this code for you by making a few assumptions.

  1. Arguments and saved state can be treated similarly. They’re both state (arguments are essentially a bootstrapped state).
  2. Arguments and state will be loaded into fields.

This allows us to annotate fields and call a couple of static methods to accomplish the same thing:

public class EditEntryFragment extends Fragment {
    @Argument private Entry entry;
    @Argument("title") private String title;
    @Argument("terms") private boolean hasAgreedToTerms = false;
    public static EditEntryFragment createInstance(Entry currentEntry, String title) {
        EditEntryFragment fragment = new EntryEditFragment();
        this.entry = currentEntry;        
        this.title = title;
        BundleButler.saveArgs(fragment);
        return fragment;
    }
 
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        BundleButler.loadArgsWithState(this, savedInstanceState);
        // use saved entry to populate form fields / load images, etc.
    }
 
    public void onSaveInstanceState(Bundle state) {
        super.onSaveInstanceState(state);
        BundleButler.saveState(this, state);
    }
}

The @Argument annotation causes Bundle Butler to generate adapters used by the BundleButler utility class to build an arguments bundle and manage the entries in the state bundle. The annotation takes an optional key to be used in the bundles. If not provided, it will use the name of the field.

Look for it to be added to maven Central shortly. In the mean time you can build it from source: BundleButler on GitHub. It’s still being developed and contributions are appreciated.

Amazon Fresh Bookmarklet

amazonfreshI recently started my trial month of Amazon Fresh and was a bit disappointed in the lack of integration the service has with Amazon.com. Specifically, there doesn’t appear to be a way to add to your Fresh cart from Amazon.com. I understand the need for different carts, but don’t understand why I can’t send to Fresh or transfer between the two. So I’ve created a quick and dirty bookmarklet that will open an Amazon ASIN in Fresh for quick addition to your cart. Just drag the link below to your bookmark bar and click on it any time you’re viewing an item on Amazon.com that you’d like to add to your Fresh cart.

Open in Fresh

Android: Widgets and Library projects

On a recent project I’m working on with my AppJour team, we chose to use the DateSlider widget for date selection in lieu of the standard DatePicker and TimePicker views provided in the Android SDK. The installation instructions involve copy-pasting various layouts and java files in with our source. While that may work, it clutters our res folders and introduces source code that we don’t want to take explicit ownership of. Having it available as a library project that we could simply reference would be a much better solution.

Continue reading Android: Widgets and Library projects

C2DM Prototype

As part of my current practicum project at CM-SV, I was asked to put together a prototype that demonstrates the capabilities of Google’s Cloud To Device Messaging (C2DM) service, or push notifications. What follows was the result:

https://github.com/patrickbaumann/c2dmprototype

c2dmprototype consists of two applications: a relatively vanilla Django server application (the Cloud part of C2DM) and an Android 2.2 application (the device part of C2DM). The demo aims to demonstrate the basic pieces of a “push to talk” application by allowing a user to send audio messages to devices by pushing them instead of requiring the battery-limited phone to poll the server. I’ll cover the purpose of the two applications below. Continue reading C2DM Prototype

The Carnegie Mellon Practicum Has Arrived!

When I got accepted into the SE masters program at CM-SV, my most anticipated and nerve-wracking course was the always-off-in-the-distance practicum. The idea of working a legitimate software project with several of my classmates caused my mind to wander, chasing all of the possibilities while the concept of working potentially full-time simultaneously on two projects had me terrified. Well, the time has finally come as the practicum kicked off one week ago, today. The nerves are all but gone and the excitement is in full swing as I learn more about the project I’ve been placed on with several of my former teammates and one that, after only a week, is already hitting it off with the group as though we’ve worked together for months.

We’re working with several NASA Ames researchers that are working on the GeoCam project being sponsored by Google. Their goal is to provide a suite of tools to disaster first responders that utilize recent advances in mobile technologies to make search efforts more efficient and effective. As the first part of the GeoCam name hints, the projects focus on incorporating the capture of geolocation data into disaster response protocols.

The most mature of the tools and the inspiration for the project name is GeoCam Photo, an image capturing application that attaches geolocation data and allows users to label and classify images before synchronizing them with a central server. This data can be useful in coordinating, documenting and analyzing the actions of disaster response team members in the field. The application consists of a client and server component, written using the Android SDK and the Django framework respectively.

Our project (or projects), which are still being brainstormed, should provide similar functionality within the disaster response domain. We’re looking into options that range from providing more direct push-to-talk communication to a status monitor that would analyze movement using a phone’s accelerometer and compass and alert search team managers when they’re in potential imminent danger. We’ve set up a Google Sites landing for the project and intend to update it regularly as we further define the project.

Ruby: Executing code only if file was called directly

I wanted a way to treat a Ruby file as both an importable library or a script. The best solution I could find was as follows:

if __FILE__ == $0
   #script / run as self code goes here
end

If the file is called directly a la ruby ./library.rb, the code within that if block will be executed. If included, __FILE__, the file that this code exists in will not match $0, the file being executed and the code in that block will not be executed.

Example

library.rb
PHRASE = "Hello World"
 
def get_phrase
 PHRASE
end
 
if __FILE__ == $0
 puts "Executing library.rb"
 puts get_phrase
end
script.rb
require "library.rb"
 
puts "Executing script.rb"
puts get_phrase

Running ruby script.rb will produce:

Executing script.rb
Hello World

Running ruby library.rb will produce:

Executing library.rb
Hello World

It seems trivial but I’ve utilized this several times while creating large collections of scripts.

Ruby: Use .each on anything

While parsing several variables that could be strings or arrays of strings, I found myself doing too much type checking and my code was getting ugly. I wished there was a way to execute each on types that weren’t containers. For instance:

#define variables
$some_path = "/path1"
$some_path2 = ["/path2", "/path3"]
 
# ... some time later ...
$some_path.each {|path| puts path}
$some_path2.each {|path| puts path}

That should produce:

/path1
/path2
/path3

Turns out, this is easy to do. Simply add the each method to the Object class:

class Object
  def each(ary)
    yield self
    return ary
  end
end

I’m not concerned with the index, so this works just fine for my needs