19 June, 2010

Launching the Android Application Manager

I recently had a need in an Android app to launch the Application Manager. After poking through the source, it turned out to be pretty easy. As you would expect, you simply create an intent and start the activity.

Here is the code to do it:

private static final String ANDROID_SETTINGS_PKG = "com.android.settings";
private static final String ANDROID_SETTINGS_INSTALLED_APP_DTL = ANDROID_SETTINGS_PKG + ".InstalledAppDetails";
private static final String ANDROID_SETTINGS_APP_PKG_NAME = ANDROID_SETTINGS_PKG + ".ApplicationPkgName";


Intent intent = new Intent();
intent.putExtra(ANDROID_SETTINGS_APP_PKG_NAME, "com.your.package");


This will launch the Application manager for the "com.your.package" app (as defined in its AndroidManifest.xml).

Creating a custom USB Mass Storage Driver

In my previous post I described how to get a USB mass storage (UMS) device recognized. This is not always sufficient, as was the case for me recently. To get around this, it was necessary to pull down the kernel source and modify and rebuild the usb mass storage driver. This blog entry describes what I did.

In my case, the device was also not forthright with it's protocol and transport, so the driver was rejecting the device. The usb-storage driver includes a header file of exception cases for just such usb devices. If you modify this file for your device, you can get around this last hurdle.

You will need to pull down the kernel source, modify one of th usb-storage driver files, recompile the kernel, and install the driver.

Step 1: Download the kernel source. Using Ubuntu, you can use synaptic or apt-get install to pull down the source. Using apt-get for instance, get it using:

apt-get install linux-source

On Ubuntu, the source will be placed in /usr/src as a tar.bz2. You'll need to unzip this. Unzipping in the same location is fine, as this is where the header files are placed anyway.

Step 2: Open "unusual_devs.h" in an editor. It should be under "drivers/usb/storage" directory.

Step 3: Add an entry for your device into "unusual_devs.h". Each entry looks like the following:

UNUSUAL_DEV( 0xbbbb, 0xb001, 0x0001, 0x0001,
"Mfg Name",
"Product Name",

I don't fully understand what all the values mean, but here is a break down of what I do know:

Field Purpose Possible Values
1 USB Vendor Id Hexadecimal
2 USB Product Id Hexadecimal
3 Device Min Hexadecimal
4 Device Max Hexadecimal
5 Vendor Name String
6 Product Name String
7 Protocol US_SC_DEVICE - Use the protocol specified by the device
US_SC_SCSI - Transparent SCSI
US_SC_RBC - Reduced Block Commands (RBC)
US_SC_8020 - 8020i
US_SC_8070 - 8070i
8 Transport US_PR_DEVICE - Use the transport specified by the device
US_PR_CB - Control/Bulk
US_PR_CBI - Control/Bulk/Interrupt
9 Init function The name of the function for initialization, or NULL if there is none.

The key values here are the Protocol, Transport and Flags. For the Protocol and Transport, chances are the auto-detect values won't work, otherwise you would not need to do this. In my case I simply guessed at the values (SCSI is a common protocol, for instance).

Step 4: Compile. Run make as root from the base kernel directory. You may need to install additional compilation tools. Verify that you have a usb-storage.ko file under drivers/usb/storage.

Step 5: Determine your running kernel version. Run "uname -r". This will return the name of your kernel.

Step 6: Install your new kernel module. While you can use the whole kernel, I simply installed the one driver. Rename the existing driver to usb-storage.ko.orig, and copy over the new driver to /lib/modules/<kernel-name>/kernel/drivers/usb/storage, where <kernel-name> is the value returned in step 5.

If all works according to plan, your new device should be recognized when you plug it in.