Recent Posts

Using Android's UriMatcher

Posted on 22 Mar 2013

When setting up a ContentProvider, I didn’t really see any good explanation of how to use the UriMatcher class. Here is a small example of it in a ContentProvider.

public class MyProvider extends ContentProvider {
  private static final int ORDERS = 1;
  private static final int ORDERS_ID = 2;

  private static final int ITEMS = 3;
  private static final int ITEMS_ID = 4;

  private static final UriMatcher mUriMatcher = new UriMatcher(
      UriMatcher.NO_MATCH);

  // The # sign will match numbers
  static {
    mUriMatcher.addURI(Constants.AUTHORITY, "orders", ORDERS);
    mUriMatcher.addURI(Constants.AUTHORITY, "orders/#", ORDERS_ID);

    mUriMatcher.addURI(Constants.AUTHORITY, "items", ITEMS);
    mUriMatcher.addURI(Constants.AUTHORITY, "items/#", ITEMS_ID);
  }

  @Override
  public int delete(Uri uri, String where, String[] whereArgs) {
    int count = 0;

    // Switch on the match, it will return the integer you passed in previously
    switch (mUriMatcher.match(uri)) {
    case ORDERS:
      count = database.getWritableDatabase().delete("orders", where, whereArgs);
      getContext().getContentResolver().notifyChange(uri, null);
    case ITEMS:
      count = database.getWritableDatabase().delete("items", where, whereArgs);
      getContext().getContentResolver().notifyChange(uri, null);
    }

    return count;
  }

  @Override
  public Cursor query(Uri uri, String[] projection, String selection,
      String[] selectionArgs, String sortOrder) {

    SQLiteQueryBuilder qb = new SQLiteQueryBuilder();

    String defaultOrder = DatabaseHelper.DEFAULT_SORT_ORDER; // "id"

    switch (uriMatcher.match(uri)) {
    case ORDERS:
    case ORDERS_ID:
      qb.setTables("orders");
      defaultOrder = DatabaseHelper.DEFAULT_SORT_ORDER_ORDERS; // "date DESC"
      break;
    case ITEMS:
    case ITEMS_ID:
      qb.setTables("items");
      break;
    }

    String orderBy;

    if (TextUtils.isEmpty(sortOrder)) {
      orderBy = defaultOrder;
    } else {
      orderBy = sortOrder;
    }

    Cursor cursor = qb.query(database.getReadableDatabase(), projection,
        selection, selectionArgs, null, null, orderBy);

    cursor.setNotificationUri(getContext().getContentResolver(), uri);

    return cursor;
  }
}

Parsing a List with Jackson

Posted on 15 Mar 2013

I started on a new Android project that pulls JSON form a web service. One of the end points returns and array of objects and I wanted to parse them into Java objects with Jackson. It wasn’t very obvious and I didn’t see this listed anywhere so I figured I’d share it.

Replace MyClass with the class you want to deserialize to.

ObjectMapper mapper = new ObjectMapper();
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);

TypeFactory typeFactory = TypeFactory.defaultInstance();
List<MyClass> my_classes = mapper.readValue(responseJson, typeFactory
    .constructCollectionType(ArrayList.class, MyClass.class));

Android SQLite Migrations

Posted on 13 Feb 2013

Migrating birds

I started up on android again and started using the SQLite database for the first time. Coming from rails I really wanted to have some kind of migrations for the database. I googled around and didn’t really see anything available so I made up a simple class that solves my problem.

Note that this hasn’t been used outside of my test app. I also have only created one migration with it so far, but I like how it went. An abstract class might also not be the best way to go, but I haven’t used it since college and wanted to try it out again.

src/org/oestrich/myapp/migrations/Migration.java
package org.oestrich.myapp.migrations;

import android.database.sqlite.SQLiteDatabase;

public abstract class Migration {
        private SQLiteDatabase mDatabase;

        public Migration(SQLiteDatabase database) {
                mDatabase = database;
        }

        public abstract void up();

        public abstract void down();

        public SQLiteDatabase getDatabase() {
                return mDatabase;
        }
}
src/org/oestrich/myapp/migrations/InitialDatabase.java
package org.oestrich.myapp.migrations;

import android.database.sqlite.SQLiteDatabase;

public class InitialDatabase extends Migration {

        public InitialDatabase(SQLiteDatabase database) {
                super(database);
        }

        @Override
        public void up() {
                getDatabase().execSQL(
                        "CREATE TABLE my_model (_id INTEGER PRIMARY KEY AUTOINCREMENT);");
        }

        @Override
        public void down() {
                getDatabase().execSQL("DROP TABLE my_model;");
        }

}
src/org/oestrich/myapp/database_helper.rb
package org.oestrich.myapp;

public class DatabaseHelper extends SQLiteOpenHelper {
        // ...

        @Override
        public void onCreate(SQLiteDatabase db) {
                try {
                        db.beginTransaction();

                        new InitialDatabase(db).up();

                        // Add more migrations here

                        db.setTransactionSuccessful();
                } finally {
                        db.endTransaction();
                }
        }

        // ...
}

Image Source

Sinatra OAuth Workflow - Use This to Speed Up Your App Development

Posted on 09 Feb 2013

This post was originally published on the SmartLogic Blog.

With this Sinatra workflow, your app development will be as smooth as Frank

When you need to connect to multiple different APIs, it can take a long time to manage your OAuth workflow for each third-party app. On a recent app development project, I was getting really agitated using cURL for every step in the process while working on pulling in data from multiple apps. So I decided to do something about it. I’m a programmer, damn it.

While I don’t have a magic solution, I created a Sinatra OAuth proxy app that works with Harvest. This sped up development for connecting with Harvest, and with small changes, the same code can also work for other applications. For example, I tested it out on Foursquare and the same code mostly worked.

This is the code I used to speed up OAuth and inspect the third party app’s API.

gist

server.rb
require 'sinatra'
require 'json'
require 'faraday'
require 'faraday_middleware'

enable :sessions

IDENTIFIER = "YOUR_IDENTIFIER"
SECRET = "YOUR_SECRET"
REDIRECT_URI = "http://localhost:3000/auth"
AUTH_URL = "https://api.harvestapp.com/oauth2/authorize"
TOKEN_URL = "https://api.harvestapp.com/oauth2/token"
BASE_API_URL = "https://api.harvestapp.com/"

# Middlware to insert "Accept: application/json" header
class JsonMiddleware < Faraday::Middleware
  def call(env)
    env[:request_headers]["Accept"] = "application/json"
    @app.call(env)
  end
end

# Redirect to the API to start the OAuth handshake
# http://www.getharvest.com/api/authentication-oauth2
# http://tools.ietf.org/html/draft-ietf-oauth-v2-22#section-4.1
get "/" do
  query_string = Rack::Utils.build_query({
    :client_id => IDENTIFIER,
    :redirect_uri => REDIRECT_URI,
    :state => "optional-csrf-token",
    :response_type => "code"
  })

  redirect "#{AUTH_URL}?#{query_string}"
end

# Harvest will redirect back here with the OAuth code you
# use to get the access token.
get "/auth" do
  query_string = Rack::Utils.build_query({
    :code => params[:code],
    :client_id => IDENTIFIER,
    :client_secret => SECRET,
    :redirect_uri => REDIRECT_URI,
    :grant_type => "authorization_code"
  })

  response = Faraday.post("#{TOKEN_URL}?#{query_string}")
  session[:token] = JSON.parse(response.body)["access_token"]
  redirect "/token"
end

# Removes favicon warnings
get "/favicon.ico" do
end

# Display your access token
get "/token" do
  session[:token]
end

# Proxy everything after / to Harvest
#
# http://localhost:3000/projects/1/entries?from=2013-01-10&to=2013-01-14
# => https://api.harvest.com/projects/1/entries?from=2013-01-10&to=2013-01-14
get "/*" do
  headers "Content-Type" => "text/plain"

  params.delete("captures")
  url = "/#{params.delete("splat").join}?"
  url += Rack::Utils.build_query(params)

  client = Faraday.new(:url => BASE_API_URL) do |faraday|
    faraday.request :url_encoded
    faraday.request :oauth2, session[:token]
    faraday.use JsonMiddleware
    faraday.adapter Faraday.default_adapter
  end

  response_body = client.get(url).body
  JSON.pretty_generate(JSON.parse(response_body))
end

How do you handle OAuth without cURLin’ all day long? Comment and let us know.

For more like this, follow @SmartLogic and @ericoestrich on Twitter.

Image Source

Tic Toc And IRB

Posted on 01 Feb 2013

My co-worker, Sam Goldman, a while back showed me this useful little IRB trick in order to get out how long a method takes. I used it pretty heavily recently with doing a call that hits the network.

It’s really easy to set up, just add the following to your .irbrc file.

~/.irbrc
def tic
  @tic = Time.now
end

def toc
  "#{Time.now - @tic} seconds"
end

Once that’s set up you can call it surrouding the method you want to time.

irb(main):003:0> tic; puts "Hello"; toc
Hello
#=> "3.0686e-05 seconds"
irb(main):004:0> tic; sleep 2; toc
#=> "2.000082375 seconds"

It’s also in my dotfiles repo on github.

Creative Commons License
This site's content is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License unless otherwise specified. Code on this site is licensed under the MIT License unless otherwise specified.