Sunday, January 15, 2012

Update: GUIs, Here's How They Work

So here's an update to a recent post : Android recently released their design guidelines for Ice Cream Sandwich. It can be found here. Some interesting things to note:

The design principals are abstract and lofty. Things like "Enchant Me", "Simplify My Life", and "Make Me Amazing" are pretty open to interpretation, but at least it gives you an idea what the designers were thinking when they created the interface.

The Style section of the site describes things like how to design for different resolutions, what themes would compliment the native UI, their Roboto font, icons, and finally writing style

The writing style is most interesting to me. Here are their main guidelines.

  • Keep it brief
  • Keep it Simple
  • Be Friendly
  • Put the most important thing first
  • Describe only what's necessary and no more
It's interesting because most of the examples they used seem to have came from their older UIs. Maybe they have gotten things right with ICS. If you got the time, I would encourage you to check out their other guidelines -- it's in interesting read (if you're in to that kind of thing).

Wednesday, January 11, 2012

Linux and ADB

Hello all!
I thought I would post a little guide on what you have to do to get adb to work with eclipse and your device out on ubuntu.
This assumes:

  • You're running Linux as a normal user
  • You've installed the Android SDK
  • You've installed Eclipse
  • You've installed the Android SDK plugin for Eclipse
I did all of that and it worked wonderfully for the emulator, but when I tried to run it on my Nexus One, it wouldn't recognize it. Since I do linux for a living, I though I would do a short writeup on what was broken and how to fix it.
Lets begin with reproduction of the problem. I'll plug in my Android device with USB Debugging turned on. Then I'll go to a terminal and type:


user@server:~/Projects/android-sdk-linux_86/platform-tools$ ./adb devices
List of devices attached 
???????????? no permissions

Well that's no fun. Note: if I had the emulator running, it would find it just fine. Well lets take a look at what went wrong. To understand the problem we are facing, you must understand that in linux, everything is accessed like a file, and files have permissions. The adb-server was having issues reading the usb device and to fix that, we must find the USB device "file" and make sure the permissions are correct on it. Devices in linux are kept under /dev/, so after looking around there a bit I find it at /dev/bus/usb/001/106 
I can do the following


user@server:~/Projects/android-sdk-linux_86/platform-tools$ sudo chown user /dev/bus/usb/001/106
<enter password>
user@server:~/Projects/android-sdk-linux_86/platform-tools$ ./adb kill-server
user@server:~/Projects/android-sdk-linux_86/platform-tools$ ./adb start-server


And now when I list my devices


user@server:~/Projects/android-sdk-linux_86/platform-tools$ ./adb devices
List of devices attached 
HT9CRP801xxx device

Huzzah! But do I have to go through that song and dance each time I want to develop? NO!
You don't even have to resort to writing your own script! You can use a function included in most linux distributions called udev. udev is a program that is ran every time hardware changes on your machine. You have the ability to write "rules" to compare the new hardware against some parameters and if  they match, you can have it do some action, like call a script or set permissions on the newly created device files. All rules go into /etc/udev/rules.d/ . Lets take a look at the rule I created.


user@server:~/Projects/android-sdk-linux_86/platform-tools$ cat /etc/udev/rules.d/99-android.rules 
SUBSYSTEM=="usb", SYSFS{idVendor}=="18d1", MODE="0666"

Basically, make a file just like that one, but change the 18d1 to match your device. It's pretty straight-forward (uh...sure), but where did that 18d1 come from? It came from the output of lsusb


user@server:~/Projects/android-sdk-linux_86/platform-tools$ lsusb
... 
Bus 001 Device 107: ID 18d1:4e12  
...

Mine had a blank description  but maybe other device would say something about adb in there to give you a hint. I know this isn't quite a step-by-step guide, but hopefully it helps someone out. Let me know in the comments if you get stuck.

Thursday, December 29, 2011

Anonymous Classes

(Or more things I should have learned in college)

One of the things that always tripped me up when I was working on open-source projects in High School was seeing what looked to me to be very strange formatting of code. It would be a jumble of parentheses and curly-braces, and it wouldn't make sense to me. Worse yet, I couldn't find a pattern to try to associate this formatting with. So I just skipped it and modified what I knew.

In College, I took a programming language course where we explored the more "exotic" languages. We got to lisp and lambda functions and once I learned about those, I had all the knowledge needed to understand the weird syntax.

It wasn't until I got into android programming that I saw funny looking code again.and then it all made sense. Here's an example:

searchBtn.setOnClickListener(new OnClickListener() {


@Override
public void onClick(View v) {
...
}

});


This threw me for a loop -- method calls are usually in the form of
          object.method(arg1, arg2, ...);
Why was there a new in there?
What's with all the curly braces?
Why wasn't the method call finished before all this new junk was put in?

Well, While I was pondering these things, it all just sort of clicked. It was an Anonymous Class.

What are Anonymous Classes?
Anonymous classes are classes that have no explicit name. As a result they are only used once.

Why Would you use one?
Because you're lazy er...because there are cases where you only need a class only to satisfy a parameter of a function. These are most useful for callbacks. Doing GUI programming, or interfacing with some type of input device, you'll see them often.

How to interpret/use one
Well lets start off with the example above. Lets look at it's method signature:
void setOnClickListener(View.OnClickListener l) ;
That's pretty straightforward, it's a function that takes one argument of type OnClickListener.
Lets look at the OnClickListener class. It's an interface. That means that you can't call a instance of that class, it can only be implemented in a class which defines all it's abstract methods. In this case, setOnClickListerner needs an instance of a OnClickListener class so that it knows what to do when clicked. Here's what you can't do:
      OnClickListener bob = new OnClickListener();
That won't compile because it has an  abstract method, onClick(View v), which needs to be defined. So we can write a class that implements the OnClickListener
class anOnClickListernerForTheStartButtonOnTheMainActivity implements View.OnClickListener {
    onClick(View v)
    {
      ...
    }
}
//In another file
anOnClickListernerForTheStartButtonOnTheMainActivity bob = new anOnClickListernerForTheStartButtonOnTheMainActivity();
searchBtn.setOnClickListener(bob);
But that gets cumbersome, so we do as the first example above does and use anonymous classes.

Hopefully this helps someone else understand the beauty of Anonymous Classes

Tuesday, December 27, 2011

GUIs? How Do They Work?

So I've been around a computer for most of my life and I've seen some pretty bad designs (cue www.timecube.com guy here), but one thing that has interest me is GUI design. I've spent 4 years in college and only had about 1 class where a GUI was required. Granted, computer science isn't about GUI programming but still, I was ill prepared to start designing programs that other people would be using.
When I started to program for android, I was a little taken aback by the XML approach to GUI programming that I had to use and searched for something that would give me a more Visual C++ type feel that I was use to in college. I found some (java warning) but I couldn't get it to do exactly what I wanted so I dug into the XML and got it under control -- but what to do with it? How should I design my app to be most usable? These are the questions I have to answer to make my app successful.

Looking back there have been some interesting Human Interface Guidelines (HIG) that have been used to try to steer people in the right direction in terms of how the look and feel of an application should be. One that comes to mind is one from the GNOME HIG. It suggested that Buttons shouldn't be labeled "OK" and "Cancel" but instead use verbs to clarify what the user is about to do.
Some people see this as putting a bounding box on their creativity and prefer to create their own way of doing things or making an app "skinnable" which I think is horrible. It breaks consistency with everything else and a lot of the time it leaves the default butt-ugly with the excuse "If they don't like it, they can change it".

No.

I don't wanna take time to find and change a skin just because you wanted to make your app extendable. Pick intelligent defaults is all I'm saying.

Another thing you have to think about these days is making an interface that is usable on many different devices. between androidx86, Chinese tablets, and car makers, you can never be sure where your app will be deployed and how it will look. Luckily the android sdk makes the experience a bit more predictable by allowing multiple versions of resources to be uploaded and letting the device choose which one to display.  Also, you specify text fonts and layout sizes in em instead of cm or px. You can still use those units but they don't scale in to different size devices. There are a lot more guidelines on how to design your app on android and they can be found Here.

Looking at it all, it can be a bit overwhelming to try to get it all right at first, that's why I'm focusing on functionally first then I can devote all my time into usability

Monday, December 26, 2011

Motivation

It's tough to stay motivated enough to see the product through to market. I look at my phone full of half completed apps, and it makes me sad.
I guess one of the reasons I don't continue is because it's such a pain to develop on my my computer. It has low ram so Eclipse crashes all the time, also I always have to futz with adb to get it to see my phone, don't even think about running the emulator -- that makes my computer go OOM everytime.

I will be getting a new computer soon and maybe then I'll be able to develop more -- I even have some more ideas of what to make. You'll hear more about those later.

--B

Thursday, October 14, 2010

Helpful Link For AppWidget Creation

Looking to get started on designing an appwidget and find that none of the tutorials on android.com have information on dealing with buttons (and other UI elements)?
I found a nice tutorial that deals with those issues and is pretty easy to follow:

http://www.helloandroid.com/files/xmaswidget/android_howto-hellowidget.pdf

Leave a comment if you've found it helpful.

Monday, October 11, 2010

Appwidget lifetimes and persistance of data

So tonight's aggravation was caused by the letter null. Basically I couldn't figure out when I was trying to get my Speed Widget to work, why I could create a locationManager and initialize it, but subsequent calls would throw a NullPointerException.

The solution (as with most things), was to RTFM. If you look at the documentation for BroadcastReceiver (Which AppWidgetProvider is extended from), you would see:
A BroadcastReceiver object is only valid for the duration of the call to onReceive(Context, Intent).
So that pretty much solved why my local variables were disappearing each time. I figured that appwidgets had funky lifetimes, I just didn't know where to look.