Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accessing android:installLocation manifest attribute

I'm trying to write an Android 2.2 app that will find installed apps that can be moved to the SD card. The permission to do this is encoded in the AndroidManifest.xml file as the root-level attribute "android:installLocation". PackageInfo seems to have an interface to everything but this attribute. I can open the installed apk and extract the AndroidManifest.xml file, but it seems to be in some binary encoding format, which some random internet people have written a decoder for, but that seems like an awful lot of work.

Is there an interface that I'm missing?

like image 779
wfaulk Avatar asked Jun 17 '10 20:06

wfaulk


1 Answers

As it turns out, while there's no direct API call to get installLocation, neither do I have to parse the binary XML manually, as the provided XmlResourceParser works on it.

// Experimentally determined
private static final int auto = 0;
private static final int internalOnly = 1;
private static final int preferExternal = 2;

AssetManager am = createPackageContext(packageName, 0).getAssets();
XmlResourceParser xml = am.openXmlResourceParser("AndroidManifest.xml");
int eventType = xml.getEventType();
xmlloop:
while (eventType != XmlPullParser.END_DOCUMENT) {
    switch (eventType) {
        case XmlPullParser.START_TAG:
            if (! xml.getName().matches("manifest")) {
                break xmlloop;
            } else {
                attrloop:
                for (int j = 0; j < xml.getAttributeCount(); j++) {
                    if (xml.getAttributeName(j).matches("installLocation")) {
                        switch (Integer.parseInt(xml.getAttributeValue(j))) {
                            case auto:
                                // Do stuff
                                break;
                            case internalOnly:
                                // Do stuff
                                break;
                            case preferExternal:
                                // Do stuff
                                break;
                            default:
                                // Shouldn't happen
                                // Do stuff
                                break;
                        }
                        break attrloop;
                    }
                }
            }
            break;
        }
        eventType = xml.nextToken();
    }

Uh, I guess there's a switch in there with one case that should probably just be an if. Oh well. You get the point.

like image 94
wfaulk Avatar answered Oct 25 '22 04:10

wfaulk