6

我正在尝试编写一个 Android 2.2 应用程序,该应用程序将找到可以移动到 SD 卡的已安装应用程序。执行此操作的权限在AndroidManifest.xml文件中编码为根级属性“ android:installLocation ”。 PackageInfo似乎对除此属性之外的所有内容都有接口。我可以打开已安装的 apk 并提取 AndroidManifest.xml 文件,但它似乎是某种二进制编码格式,一些随机的互联网人已经为其编写了解码器,但这似乎是一项非常艰巨的工作。

是否有我缺少的界面?

4

4 回答 4

12

事实证明,虽然没有直接的 API 调用 get installLocation,但我也不必手动解析二进制 XML,因为所提供的XmlResourceParser适用于它。

// 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();
    }

呃,我猜里面switch有一个case可能应该只是一个if. 那好吧。你明白了。

于 2010-07-07T04:00:05.230 回答
0

考虑到清单标记的所有其他直接属性都可以从 PackageInfo 中获得,我认为您在那里寻找它是正确的。

我知道它不在文档中,但是您是否尝试过?就像是

PackageInfo pkg = ...;
String loc = pkg.installLocation();

我知道这可能是非常幼稚的,考虑到文档甚至可能是自动生成的——如果我自己可以尝试的话,我不敢建议它(由于 8 不再支持延迟操作系统,目前卡在 API 7 上)

如果它不起作用,恐怕他们只是忽略了这一点——我无法想象他们会突然把它放在其他地方。在这种情况下,您可能会被困在自己解析清单的过程中。

于 2010-06-19T08:53:18.670 回答
0

在 2007 年的旧 API 中,PackageInfo 类中有公共字段,提供有关 internalLocation 和其他相关信息的所有信息。出于安全原因,我猜他们摆脱了那些方便的领域。

于 2012-02-08T23:25:53.440 回答
0

您可以通过下一个示例访问此属性:

PackageInfo packageInfo = context.getPackageManager().getPackageInfo(mPackageName, 0);
if (packageInfo.installLocation != PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
    .....
}


在 API 21 中引入了http://developer.android.com/reference/android/content/pm/PackageInfo.html#installLocation

但是即使在 Android 2.3 中也存在这个字段 http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.3_r1/android/content/pm/PackageInfo.java/

于 2015-02-26T14:42:10.100 回答