Menu

Time to bump minSdk to 16

It was about time: API levels 14-15 are falling behind pretty quickly.

We can see in this image, from a sample of about 200k sessions, how the 4.0.+ accounts for only ~6% and rapidly decreasing.

SalsaLoL

It's not that I particularly need any API introduced in 16 in a daily basis (except maybe using fontFamily as it is intended to be done), but if we don't keep pushing we will be forever stuck in 14 as we were for years in 8-9.

So, let's go for it and use API 16 as minSdk for the next projects! :)

Going freelance

After almost 3 years coding for Mobivery, the adventure comes to an end. I am really grateful for the time I've spent there, as I've met great people, learned a lot and worked with awesome professionals.

But it's time to start a new adventure.

I have been doing for a couple of months some work on my own apps (the Speed Cameras application for Spain, United Kingdom, Australia and New Zealand and more to come) and SalsaLoL with my friends of Redfive Labs.

I already have some clients lined up for the near future, but of course I'm up for some contracting. You could contact me anytime if you need some Android or iOS consultancy or project that needs to be done.

// I did my part
nacho.setJob(JobFactory.buildJob(Jobs.FREELANCE));

// Now you do yours! :)
JobType newJobType = JobType.CONTRACTING; // or CONSULTANCY or DESIGN  
if (nacho.hire(new AwesomeProject(newJobType))) {  
  client.setProfit(Double.MAX_VALUE);
  client.setHappiness(Integer.MAX_VALUE);
}

Radares España, SpeedCams ES

My new app is a speedcam notifier for spanish roads. It is intented to be a base for making apps for other countries.

App logo

I have called it Speedcams ES (Radares España in spanish), pretty unoriginal and boring but that's how it is. I will come up with a better one, I'm sure of it. The beauty of the Play Store is that I can change it whenever I feel like it so it doesn't really matter that much.

I already did one app like this in the past for a hackathon at work, but never got released. So I had the know how and a thorn in the side with that app, so when I thought about what app should I do next, this one app came to mind.

Main interface

I prototyped and created the design and icons with Sketch 3. It is a really good piece of software. I also used Skala Preview and this plugin for being able to test it on my device.

It is simple, yet effective. I sincerely dislike the enterprise-looking or iOS-looking alternatives we have on the spanish Play Store.

Speedcam detected

I was able to experiment with some things I wanted to try out. I used

Using delayed_job with class methods

A bit of context before going to the solution...

I was trying to call a bulk insertion of some objects in the database in a Rails app hosted in Heroku, taking data from an user uploaded CSV file and processing it via find_or_create_by for each row, updating all the attributes when necessary and finally persisting the data in the database.

As the data rows grew in number (over 5k entries usually) the timeout limit of 30 seconds imposed by Heroku wasn't enough. So I had to setup the delayed_job gem with the HireFire gem for a cheaper experience in Heroku for the bulk process.

So I did it this way.

# controllers/the_model_controller.rb
TheModel.delay.import_from_csv params[:file]  # The offending line  
redirect_to root_url, notice: 'Data inserted successfully'

# models/the_model.rb
class TheModel  
  def self.import_from_csv(file)
    CSV.foreach(file_path, headers: true) do |row|
      temp_stuff = row.to_hash
      the_model = TheModel.find_or_create_by(:attribute1 => temp_stuff['attribute1'])
      # ... fill with data
      the_model.save!
    end
  end
end  

With the delayed_job ruby gem I was always getting undefined_method errors.

Routing Error  
undefined method

SwipeRefreshLayout with ListView done right

Setting up a SwipeRefreshLayout is pretty easy. There are great tutorials out there. Even more if you already played around with other compat components like the DrawerLayout.

You just wrap your ScrollView or ListView, a few wiring here and there, and it's done. Works flawlessly, with just a few lines of code.

But what if you want to use a ListView, but you need something else besides a ListView as SwipeRefreshLayout's only child?

Maybe you want to use an empty view for all those times the list comes up empty. Or you want to put any extra view, like a SmoothProgressBar anywhere. Or a loading spinner at the center of the screen while it's loading.

Image a layout like this one.

<android.support.v4.widget.SwipeRefreshLayout  
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/swipe_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:text="@string/guides_no_results"
            android:id="@+id/empty_view"
            android:gravity="center"
            android:padding="16dp"
            android:fontFamily="sans-serif-light

GitHub Downloader

I have created a new gem, GitHub Downloader, which does basically that: it downloads the source code from GitHub repos, packed in zip files.

Octocat rules!

It's open sourced, of course. You have in there the usage instructions too.

I needed an script for doing that, and well, maybe it works for other people so there you have. It's on RubyGems already, give it a try if you find an use to it!