Listing connected Android devices with OS version and model

I was wandering down the path of trying to associate the myriad of devices connected to my machine for debugging. I wanted to know very easily what the devices’ model and OS version were without having to manual check by disconnecting and reconnecting devices and using the process of elimination.

One way to see this information is using a special flag with adb:

adb devices -l

This yields something like

List of devices attached
HT16JHX24920           device usb:14130000
015d2a506750081b       device usb:14120000 product:nakasi model:Nexus_7 device:grouper
4d005e148cc950eb       device usb:14112000 product:ja3gub model:GT_I9500 device:ja3g
0A3BC06A11010002       device usb:14140000
e08b84fd               device usb:14113000
HT346W912280           device usb:14114000

Which as you can probably tell doesn’t give us all of the information we want, nor does it seem to work on every device.

So instead, I wrote a script for printing out what I needed. The bash script reads properties from the device via adb shell.

The output for that looks like:

HT16JHX24920         [ 4.0.3]: PG86100
015d2a506750081b     [ 4.4.2]: Nexus 7
4d005e148cc950eb     [   4.3]: GT-I9500
0A3BC06A11010002     [ 4.1.2]: DROID RAZR
e08b84fd             [ 4.1.1]: SAMSUNG-SGH-I747
HT346W912280         [ 4.1.2]: HTC One

View, download, or fork the script

In case you were curious, the corresponding properties are:

$ adb shell getprop ro.product.model
PG86100

and

$ adb -s HT16JHX24920 shell getprop ro.build.version.release
4.0.3

Making Borders for Views Using layer-list

Android is full of many ways to do things differently. One of those things happens to be making a border for a View.

The common approach I’ve seen is for developers to have two Views. One View is the View with a background (be it solid, bitmap, or otherwise). The other View acts as a border, typically either 1px or 1dp in width or height, the other side matching the height or width of the other View. Although this is certainly an easy approach, at adds more to your layout than is likely necessary.

Example with Views:

<View
    android:layout_width="match_parent"
    android:layout_height="1px"
    android:background="#ccc" />

<TextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="#eee"
    android:text="Hello, World" />

Assuming those Views are encapsulated in a LinearLayout with vertical orientation, you’ll end up with a TextView with background of #eee and top border of #ccc.

Now, let me introduce you to layer-list

layer-list allows you to do many things regarding multiple drawables. One of the more common implementations is adding a border to something.

I’ll explain by example:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape>
            <solid android:color="#ccc" />
        </shape>
    </item>
    <item android:top="1px">
        <shape>
            <solid android:color="#eee" />
        </shape>
    </item>
</layer-list>

What this example shows is the layer-list way of going about the previous example. This will produce a drawable that has a 1px solid top border colored #ccc and a background of #eee. The confusing part to this for most people tends to be where the 1px is designated. layer-list draws top-down in the XML. This means that #ccc is drawn in the full background first, and then #eee is drawn over top of that, with a 1px top offset.

A Better Parcelabler…

A little bit ago (okay, a long time ago) I wrote a blog post about a tool I wrote for creating Parcelable implementations for Android. At time of writing, I knew it wasn’t a great solution, but that at least it worked… Since then, I constantly put off writing what I thought would be a better solution: an IDE plugin.

So last week, I embarked upon the journey of making a plugin for Android Studio. I immediately saw that something existed, but it was a bit older, and not quite as feature-packed as I had hoped. So, I took it upon myself to make some enhancements and submit a pull request.

I’ll be continuing development under my fork, where you’ll always be able to grab the latest as I work on enhancements. Please feel free to fork and submit pull requests as well.

Check out the plugin…

Moving to New Opportunities, New Things, New York…

Over six-and-a-half years ago, I joined a small startup, MeetMe (then myYearbook), of around 20 or 30 employees in the small, artsy town of New Hope, PA. Over the years, MeetMe provided me with many opportunities to grow and learn, allowing me to transition from a full stack web engineer to an Android engineer. I truly am grateful not only for the opportunities that I’ve been given, but also for the team that I’ve gotten to work with.

But then, there is change. I’ve decided to make a transition and move on to new opportunities. I can’t express how excited I am to transition to my new role as the lead Android engineer for SeatGeek, a search engine of sorts for finding great tickets to events — be it sports, theater, music, or otherwise.

I’m excited for all of the new challenges I’ll face working with the SeatGeek team, and I wish all of the best to the MeetMe team as they continue to help the world meet new and interesting people.

Android Animation: Bringing Your Application to Life

At MeetMe, we have a yearly internal conference wherein we invite folks internal and external to speak to the team (en masse & in breakouts) about emerging technology, trends, core company bits, etc. My core focus this year has been about spicing up our Android applications through exceptional UI/UX specifically using the grace and beauty of animations. As they say, sharing is caring, and I want everyone else to have access… so please, take a look through my presentation. If you have feedback, questions, hate mail, or anything else — please comment below.

Screen Shot 2013-12-31 at 17.15.49

 

 

 

 

https://speakerdeck.com/dallasgutauckis/android-animation

Android: putting a ViewPager inside a ListView

So, I’ve been Googling for a while to find a clean, reasonable approach for putting a ViewPager inside of a ListView (or any vertically scrolling element). The problem with putting a ViewPager inside a ListView is that it takes only a small amount of vertical (Y) delta before the ListView begins to consume touch events instead of delegating to the child in order to enable the scrolling of the ListView. That’s fine, but the problem often occurs after the ViewPager has already started processing a page change (when dragging horizontally), producing a poor user experience resulting in the improper pagination and scrolling of the two views.

There are a few ways to try to handle this.

  1. You could not do it at all (thanks Dianne and Mark)
  2. You can set a touch listener on the ListView and try to delegate the touches based on which view you think needs to get the touches and what actions need to occur based on those touches.
  3. You can also combine a touch listener with GestureDetector to try to make the implementation a little less cumbersome. The problem is that in some ListViews, our layouts are a little more complex than single item rows of text. If the item layout has for instance a Button, we’d then need to properly delegate the touch event down to the Button. This obviously has huge ramifications for implementation and testing.

In order to avoid the aforementioned shenanigans, I added an OnPageChangeListener to the ViewPager and based on the state of the pager, forced a touch delegate from the Activity.

Contrived example:

class MyActivity extends Activity {
    private ViewPager mViewPager;
    private View mTouchTarget;

    @Override
    protected void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        setContentView(R.layout.example);

        mViewPager = (ViewPager) findViewById(R.id.view_pager);

        mViewPager.setOnPageChangeListener(new OnPageChangeListener() {

            private int mPreviousState = ViewPager.SCROLL_STATE_IDLE;

            @Override
            public void onPageSelected(int position) {
                // NO-OP
            }

            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
                // NO-OP
            }

            @Override
            public void onPageScrollStateChanged(int state) {
                // All of this is to inhibit any scrollable container from consuming our touch events as the user is changing pages
                if (mPreviousState == ViewPager.SCROLL_STATE_IDLE) {
                    if (state == ViewPager.SCROLL_STATE_DRAGGING) {
                        mTouchTarget = mViewPager;
                    }
                } else {
                    if (state == ViewPager.SCROLL_STATE_IDLE || state == ViewPager.SCROLL_STATE_SETTLING) {
                        mTouchTarget = null;
                    }
                }

                mPreviousState = state;
            }
        });
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        if (mTouchTarget != null) {
            boolean wasProcessed = mTouchTarget.onTouchEvent(ev);

            if (!wasProcessed) {
                mTouchTarget = null;
            }

            return wasProcessed;
        }

        return super.dispatchTouchEvent(ev);
    }
}

Now, we have a ViewPager that retains control of touch events once the page starts changing and releases it when paging is idle or settling.

Renaming files by pattern

Occasionally (and especially when receiving assets) I have the need to rename multiple files at once — often by some sort of pattern. For instance, I may need to rename all files with the string "_msg" in it where the file ends with ".png". Previously, I might have manually found and renamed all of them or written some hack of a bash “for loop” to iterate over a find result. Neither options are quick or easy.

Recently, I found a great and simple util called rename to quickly and easily rename files with simple search-and-replace functionality.

In this example, I’m renaming any .png file under a drawable folder, replacing _msg with _message.

rename s/_msg/_message/ drawable*/*.png

The rename util (not the same as mv) comes standard with most linux installations, but I’m on Mac OS X and that means I have to get it separately. In order to easily get rename, I use homebrew.

  1. Install homebrew.
    ruby -e "$(curl -fsSL https://raw.github.com/mxcl/homebrew/go)"
  2. Install rename
    brew install rename
  3. Done.

Android & Me