Android Dialogs and onContextItemSelected()

ListViews and GridViews are great widgets to use in an Activity for your app. Sometimes it is useful to also create smaller versions of them for dialogs within your app. There’s only one problem: Context Menus. If you have tried to put a context menu on a ListView inside a dialog, you may have found out that while onCreateContextMenu() is called, onContextItemSelected() is not. There is a workaround, though, because onContextItemSelected() is actually a convenience method called from onMenuItemSelected(int, MenuItem). If you add the following method to your dialog containing the ListView (or GridView), you will find that onContextItemSelected() is working again.

@Override
public boolean onMenuItemSelected(int aFeatureId, MenuItem aMenuItem) {
    if (aFeatureId==Window.FEATURE_CONTEXT_MENU)
        return onContextItemSelected(aMenuItem);
    else
        return super.onMenuItemSelected(aFeatureId, aMenuItem);
}

 

Android: Programmatically Show the Soft Keyboard, If Needed

If you are expecting user input, a polite app will check to see if there is a hardware keyboard and if one is not present, then automatically display one so the user does not have to click the edit box first in order to pop one up. This kind of behavior is especially nice if there is only one input box being presented. While there are a few methods available out on the net in various places, I wrote my own to be compatible with Android 1.5+ and works in all cases where a keyboard is not part of the physical device as well as does nothing if a physical device has a keyboard.

The source code provided is written from the perspective of a static utility class.

    /**
     * Show soft keyboard if device does not already have a hardware one available.
     * @param aView - the View that will receive the keyboard input
     */
    public static void popKeyboard(final View aView) {
        aView.post(new Runnable() {
            @Override
            public void run() {
                ((InputMethodManager)aView.getContext().getSystemService(
                        Context.INPUT_METHOD_SERVICE)).showSoftInput(aView,
                        InputMethodManager.SHOW_IMPLICIT);
            }
        });
    }

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 Market vs. Drawable XML

Android drawable resources include the ability to provide and XML resource that specifies a different name for it’s bitmap resource.  It is an especially handy mechanism for library code to refer to a specific drawable resource that your app provides under a different name.

For example a drawable xml named “app_icon.xml” could contain:

<!--?xml version="1.0" encoding="utf-8"?-->
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
    android:src="@drawable/ic_MyAppName"
/>

If you used this kind of resource as your application’s icon resource inside your AndroidManifest.xml file, though, you have a problem. While technically, the app will function normally, the Android Market tries to check to make sure your app’s icon meets some guideline criteria and cannot handle an XML drawable. Android Market will refuse to upload your app and tell you “The icon for your application is not valid. Please use a 48×48 PNG.”

If you use XML drawables, please keep this limitation in mind and do not reference them inside your AndroidManifest.xml.

Android: Update to Postmortem Reports via email

With the addition of an Activity stack to my portmortem email reporter, it became apparent that relying on the garbage collector to restore the original exception handler was not an ideal solution. I have added a new method called restoreOriginalHandler() that should be called in your Activity class’s onDestroy() method.

public class MyActivity extends Activity {
    protected PostMortemReportExceptionHandler mDamageReport = new PostMortemReportExceptionHandler(this);

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mDamageReport.initialize();
    }

    @Override
    protected void onDestroy() {
        mDamageReport.restoreOriginalHandler();
        mDamageReport = null;
        super.onDestroy();
    }
}

Original post, updated.

Updated code link (copied from original post):
Full Source

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