Android ListView and setSelection

Android’s ListView is a powerful class that is capable of presenting a list of whatever you wish fairly easily. One of the issues that has vexed me has been scrolling the ListView to a particular entry. While newer Android versions have provided better support in this area, trying to maintain backward compatibility with Android 1.5 presents some challenges. In light of this Google issue and it’s comments, I have come up with a decent method of scrolling a ListView to a particular position if it is not already visible. I clear the focus after setting the selection because users became confused at why an “orange box suddenly appeared” when they did not expressly tap a selection with their finger or scroll with the trackball.

//this method would be part of a ListView class
    @Override
    public void scrollToPosition(final int anItemPos) {
        if (anItemPos!=AdapterView.INVALID_POSITION) {
            int theFirstItemPos = getFirstVisibleItemPos();
            int theLastItemPos = getLastVisibleItemPos();
            if (anItemPos<theFirstItemPos || theLastItemPos<anItemPos) {
                getListView().post(new Runnable() {
                    @Override
                    public void run() {
                        getListView().setSelection(anItemPos);
                        getListView().clearFocus();
                    }    
                });
            }
        }
    }

Picking a Contact photo with Motorola Cliq

Some Motorola Cliq phones are having issues trying to pick a contact photo using something other than the Gallery app that comes with the phone. Motorola is aware of the issue, but I am trying out a workaround for it in my File Browser app. Basically, the problem is that an OutOfMemoryError could result from attempting to pick a large photo because the Intent being used does not specify the size to be returned. Normally, I would just use getIntExtra(“outputX”,defX) and getIntExtra(“outputY”,defY) in order to get what the caller wanted as a size, but since Motorola’s contact app does not provide those Intent Extras, it would return the full sized photo.

Instead of waiting for Motorola to modify their app, I decided to check the name of the caller and provide a default size for that particular app.

if (myActivity.getCallingPackage().equals("com.motorola.blur.contacts")) {
    outputX = outputY = 48;
}

Android Dialog Button onClicks

One practice I’ve come to standardize in my apps has been to take dialogs with buttons that perform some kind of action or processing and then dismiss the dialog and instead place that dismiss() call as the very first line within the onClick handler.

new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        my_final_dialog_var.dismiss();
        Thread.yield(); //optional
        /* do my action here */
    };
}

On some of the more sensitive operations (like file delete), I even put a Thread.yield(); after the dismiss so that the dialog will be sure to go away before any more processing is done. The reason you want to dismiss the dialog right away is so that you avoid getting occasional double presses in case the phone is slow to perform your process or action. Nothing is worse from a user’s perspective than to have the phone not react fast enough and so will keep pressing buttons in the hopes that it will finally do something. If you code your buttons to do something each time a button is clicked, then you can have potentially disastrous results. In my case, having multiple file deletes would be a disaster when the user only wanted to delete one file and the phone just hiccuped on the confirmation dialog. Immediately dismissing the dialog gets rid of the temptation to hit the button multiple times while it is doing it’s job.

Android: Sharing Resources in Eclipse

The resources of an Android project are difficult to share between projects. In order to create a common library of widgets that reference resources is no simple task and yet is something quite desirable. Creating a “Save File” generic dialog and being able to share it amongst various Android projects not only as an Activity, but as a class ancestor that can be descended from and modified for various specialized cases is a highly desirable feature. I am used to having such a feature in the past with other languages (like Delphi’s Forms) and have been frustrated with Android projects in Eclipse. The various techniques available to potentially share resources all have their fatal flaws. Continue reading

findViewById slow inside ListView adapters

I was reading an article over on charlie.collins’s blog about using a ViewHolder class to cache the results of a findViewById() when used inside the getView() of a list’s adapter. I gave his recommendation a try and I did notice a speed improvement in my app so the observation that findViewById() is a performance hit has enough merit to go out of your way to enable some kind of caching mechanism.

While Charlie went the route of creating a class to hold the various views he was interested in, I decided to take a slightly different approach and make use of the alternative setTag(int, Object) function instead. Continue reading

Working with Android Libraries and shared code

One of the issues that has irked me for quite a while is the fact that there is no easy way to work with a set of shared code between apps in Eclipse that simultaneously gives me instant access to modifying the shared library and also the flexibility of including only the pieces of it that are needed while excluding the rest. Android Library Projects are a big step forward in helping to create a set of shared resources as well as code, but they still lack the flexibility of only including just what you need (not to mention Library Projects cannot use other Library Projects). Continue reading

Trouble browsing the web?

I recently helped out a guildie with a strange problem.  He couldn’t browse the web using Internet Explorer, nor play WoW, but he could log into Vent just fine.  My first thought was that he got a virus that prevented browsing and started giving him suggestions on how to clean his system and recommending borrowing a friend’s computer to facilitate it.  While giving out this advice, it struck me to try one more thing before writing this off as a malicious virus (which is usually the case when something like this occurs, sadly).

I quickly opened a CLI box and did a quick ping on www.google.com to find out it’s IP address.  I then relayed that address over Vent and had him type it into the browser address box.  Up came Google for him!  What did this tell me?  It told me that his computer was NOT infected with a virus (thankfully!) and that his ISP’s Domain Name Servers (DNS) went offline which meant he was trying to browse the internet blind (meaning he could only use IPs and not their friendly names).   Luckily, there are public DNS that can be used, but the process to tell your computer to use them is anything but easy.  I figured it would be a good idea to put a few resources together to help others out in such a situation, if not directly, at least a friend can help them out by having this information at hand.  I walked him through setting up his computer to use Google’s public DNS and afterwards he was able to surf the web and play WoW as if nothing was wrong.  Woot!

Google runs a public DNS on:
Primary: 8.8.8.8
Alternate: 8.8.4.4

OpenDNS also runs public DNS and seems a bit more responsive:
Primary: 208.67.222.222
Alternate: 208.67.220.220

Now for the hard part… instructions on how to tell your network connection to use these public servers rather than whatever your ISP gave you.  Thankfully, OpenDNS has some very good instructions with images to help you with each OS.

Configure MS Win7

Configure MS Vista

Configure Mac OS X 10.5 (Leopard)

Configure Max OS X 10.4 (Tiger)

Other OS instructions can be found here.

Props go out to OpenDNS for both supplying public servers and some very handy instructions for setting up your system to use them.

Safer Browsing

One of the problems with using the Internet is the vast amount of security issues encountered that can lead to getting your PC infected with all kinds of nastiness.  Some so bad that you need to wipe the PC clean and start over from scratch.

Some people tend to get infected a lot, while others rarely ever get an infection.  What’s the difference between them?  I think it’s a combination of the tools used as well as the habits employed.  I have rarely gotten infected and I would like to share some of my tools and habits so that others may benefit.

The tools I use to keep my system safe are actually a pretty light on the Anti-Virus side of things.  My main system runs MS Vista Home Ultimate (I hate it, will change eventually, but I’m stuck with it for now) and I keep it’s built in firewall up at all times.  I do not run the Security Manager, however.  I use Clamwin as my anti-virus software for two very important reasons.

  1. it does not constantly run in the background which would slow everything down
  2. it is free for personal and business use.

What this means is that I do not actually have an Anti-Virus constantly running on my system trying to protect me from harm.  I find this shows just how effective those products are while at the same time highlights the effectiveness of my browser tools and habits.

My browser of choice is Firefox with three extensions that I consider vital to safe browsing.

  1. Flashblock – blocks Flash from automatically playing on page load
  2. NoScript – blocks scripts from automatically running on page load
  3. Blitzbleiter (recently added) – blocks Flash from running if not 100% Flash compliant

When I visit a website I do not trust, I get a lot of content blocked automatically.  This may result in some ugly pages if they rely heavily on Flash content and/or scripting.  The nice part about NoScript is that you get to choose exactly which domain you will allow to run for any particular page.  For example, on Twilight’s own site, you get the choice of allowing twilightonalex.com, wowhead.com, and google-analytics.com to run their scripts.  You can choose to only allow twilightonalex.com so that menus will work while denying anything else to run since you may not trust it.  This is quite handy, for example, in forbidding the ad network quantserve.com from running scripts while allowing the site using the ad service to function.

How do I know whom to trust?  That is a very good question.  Experience and searching for site reviews are useful tools.  Doesn’t this kind of distrust slow you down?  Yes, and no.  While individual site browsing is hampered a bit, I find that avoiding a system reinstall is worth it in the long run.

By the way, if you want a direct link to download the most recent Adobe Flash installer without the ‘download manager’ crapware which also tries to install ‘free <insert-latest-CrapWare-I-don’t-want>’, here you go:

Hoping for a safer browsing future for everyone!  Take care!

Using a SubMenu in a ListActivity’s Context Menu

One of the limitations of Android’s ListActivity’s Context Menu is that if your context menu gets too large to fit comfortably into one list, shortening it by putting several items into SubMenus requires special handling in onContextItemSelected().

Context menus, by definition, are transient and will be thrown away as soon as they disappear from view. Once you click on a MenuItem that displays a SubMenu, clicking any item in that SubMenu will call the onContextItemSelected(), as expected. What is not expected is that the standard call to get the MenuInfo will return null. Continue reading