Sometimes error messages don’t really do their job and tell you how to rectify them, like this one I found today in Android Studio (v0.4.5). While attempting to add a page indicator for my ViewPager, I got “CirclePageIndicator is not allowed here.”

Way to be ambiguous...

As it turns out, this is less about Mama Android telling you where to put your controls, and more about using the correct namespace when adding controls (I had only copied over this class, not the whole project).

Mind your namespaces!

$ logout

After a fun day of attempts at crossgrading one of my machines to 64-bit Lubuntu, I needed to move my old local MySQL data to my new hard drive.

  1. Copy database folders stored in /var/lib/mysql/
  2. Change ownership of all databases to to mysql user: sudo chown -R mysql:mysql /var/lib/mysql/{my_database,my_other_database}

Done!

$ logout

LunchTable (600 commits)
LunchTable

In-progress Android app (44 commits)
New Android app

I love working from the command line. And while I can quickly open and hack away at any terminal in Ubuntu, I noticed a laggy experience on my MacBook Pro in iTerm2. Typing commands didn’t bug me as much as editing in vim, which would slow considerably when scrolling through a file.

I tried changing the font and upping the keystroke repeat rate (which needed to be done anyways), but all to no avail. It wasn’t until I plugged in a second monitor that I noticed the real issue: my Retina display; iTerm was snappy on my non-Apple 1080p monitor.

It looks like this has been an issue for a while. For now, it’s back to Terminal.app for me.

$ logout

After creating a new project in Android Studio 0.3.1 utilizing Gradle, opening the project on a new machine gave me a few problems.

First, I got: Gradle could not resolve all dependencies.

To fix this, I opened the SDK Manager and downloaded the Android Support Library, since com.android.support:appcompat-v7 isn’t in Maven Central.

Next, I got: Could not execute build using gradle installation.

To fix this, I opened a terminal and ran gradle build. Ubuntu informed me it wasn’t installed, so I:

  1. downloaded it
  2. moved it to /opt/gradle
  3. went to Settings > Gradle in Android Studio
  4. under Project-level settings, selected Use local gradle distribution
  5. changed both Gradle home and Service directory path to /opt/gradle
  6. restarted Android Studio

And everything worked!

$ logout

I’ve accumulated a few laptops over the past five years. My first laptop “lasted” for four years of college (i.e. killed its first hard drive and was running Vista for most of its career), but I’ve since moved on to more powerful, non-Windows machines. Though four computers may seem a little unnecessary to my girlfriend, each still serves its own purpose in the various virtual ventures I partake in today.

Dell Inspiron · Windows 7 · Previously, my primary computer. Currently hooked to my MIDI-enabled piano for any time I want to work on some music. Occasionally turned on and remote desktop’d into when I really need IE or Photoshop.

System76 Gazelle Professional · Ubuntu 13.04 · Primary computer for everything; mostly-permanent denizen of my desk hooked to an external mouse, keyboard, hard drives, and second monitor.

Apple MacBook Pro · OS X 10.9 · Day job computer; occasional development and double pixel-density web testing at home.

Lenovo ThinkPad X201 · Lubuntu 12.10 · Primary “laptop,” i.e. portable computer; pretty much a dedicated development machine and replacement for my Samsung N130 netbook, whose two-year use inspired my full switch to Linux, and whose left-clicker recently went kaput.

$ logout

In case you want to make a TextView clickable, simply setting an onClick handler won’t do it. Make sure you set your android:clickable attribute:

...
android:onClick="doMagicalThings"
android:clickable="true"
...

$ logout

In one app I’m working on, we’re using a ListView to display a near-realtime stream of posts by various users. However, with constant updates, it was easy for any post a user is reading to get bumped down out of view due to new items being added at the top. This is how I fixed it.

The flow to this solution is:

  1. Finding what index of the list we’re currently scrolled to (+/- the pixel offset, for more exactness),
  2. Adding our new posts at the top,
  3. Doing a notifyDataSetChanged(),
  4. Waiting for our new items to be drawn to calculate our new scroll position.

We’ll start before our for loop / add()ing block, inside the method that checks for new posts (in our case, onLoadFinished()):

// Set up vars to track current scroll position / number of
// posts already displayed
boolean newPosts = false;
int scrolledToIndex = 0;
int topOffset = 0;
int startCount = mAdapter.getCount();

// If we've received new posts, we'll set our current scroll
// values:
if (/* ...we've detected new posts... */) {
    scrolledToIndex = getListView().getFirstVisiblePosition();
    View v = getListView().getChildAt(0);
    topOffset = (v == null) ? 0 : v.getTop();

    newPosts = true;

    // Add new posts...
}

// Update the ListView
mAdapter.notifyDataSetChanged();

// Get number of new posts
int delta = mAdapter.getCount() - startCount;

// Set final variables
final int finalTopOffset = topOffset;
// The index of our first visible post has changed by delta
final int finalScrollToIndex = scrolledToIndex + delta;

// Wait until list has drawn our new posts before scrolling
// to our previous location
getListView().post(new Runnable() {
    @Override
    public void run() {
        try {
            getListView().setSelectionFromTop(finalScrollToIndex, finalTopOffset);
        } catch (IllegalStateException e) {}
    }
});

$ logout

I very recently had a conversation with a client about implementing email notifications for his online community built with my software. There was, of course, an urge in him to notify users every time the equivalent of a thread is created or responded to. There was also the need for an email to go out as soon as a personal message was received.

For the latter, I was on board; but for the former, I had to make a point– no matter how subjective. My point was that I will unsubscribe from any site’s mailing list the minute I get an email with things I don’t care about. Emails are on the level with text messages for me, arriving on my phone with an envelope notification, pining to pull me away from reality the minute it arrives. And it’s not that my time is money, but because I loathe spending time reading random minutia that I hate your everyday “engaging” emails (especially when they arrive every day).

Needless to say, I made the point that when designing a product and how it will send out notification emails, it’s important to remember:

  • You’re not the only site that any given user is a member of.
  • People have vastly varying degrees of tolerance for emails meant only for getting them to your site again.
  • Don’t automatically opt users in. Unless your software is going to take me out to dinner and learn my quirks first, don’t assume you know how I like my email notifications. Instead, give me the choice and demonstrate why your notifications will be useful to me.

On a related note, LunchTable just got email notifications today, unsent until you subscribe.

$ logout

I have a ton of movies. When I first got a Raspberry Pi late last year, my first thought was to use it as a media center. So I hooked it up to my high-def TV and a hard drive with some very old pirated Simpsons episodes (from the days of Napster), and installed Raspbmc on an SD card. It worked great, and despite the need to get up and plug it in, and the $10 wired keyboard I used to control it, it worked great. If I had more money at the time, I would’ve gone with a Wi-Fi dongle so I could use my phone as a remote, or at least gotten a wireless keyboard.

A few months went by before my parents came up with a spare Blu-ray player that also happened to support DLNA— finally, I could be lazy again. I hooked the Pi straight into my router upstairs, plugged in the harddrive, and installed MiniDLNA. Downstairs, the Blu-ray player picked it up and instantly I had access to all of my digital video.

But soon, I craved more. So I decided to convert my DVD collection.

Converting

HandBrake turned out to be the best software for the task, both for its abilities and propensity for any OS you’re using (like Ubuntu). Ripping is pretty straightforward:

  1. Insert the DVD, click Source
  2. I used the dropdown to select my DVD drive (/dev/sr0)
  3. Hit okay, it starts scanning
  4. Select the title with what should be the duration of the movie. If you’re having trouble, check out When HandBrake won’t rip your DVDs.
  5. I’m happy with my 90-minute movies taking up around 1 GB– my 1 TB harddrive can handle it. So I started with the High Profile preset, and made the following changes:
    1. Format: MKV
    2. Video
      1. Framerate: Constant
      2. Constant Quality: RF: 16
    3. Audio
      1. English Track – Mix: Dolby Surround
  6. Press Start and let it run in the background.

These settings were perfect for a high quality video of moderate size in a format supported by my Blu-ray player. Experiment to see what works best for you.

On my machine, it takes about 25 minutes to transcode a 90 minute movie, with my CPU load hovering around 9 or 10. I couldn’t get my 5 year old Dell with an Intel Core 2 Duo processor to complete a whole rip, though it does like to overheat a lot these days. Enjoy!

$ logout