Я пытаюсь записать приложение для Android 2.2, которое найдет установленные приложения, которые могут быть перемещены в SD-карту. Разрешение сделать это кодируется в файле AndroidManifest.xml как атрибут корневого уровня "android:installLocation". PackageInfo, кажется, имеет интерфейс ко всему кроме этого атрибута. Я могу открыть установленный apk и извлечь файл AndroidManifest.xml, но это, кажется, находится в некотором двоичном формате кодирования, для которого некоторые случайные интернет-люди записали декодер, но это походит на очень большую работу.
Существует ли интерфейс, который я пропускаю?
Оказывается, хотя прямого вызова API для получения 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();
}
Эээ, я полагаю, там есть переключатель
с одним case
, который, вероятно, должен быть просто if
. Ну что ж. Вы уловили суть.
Учитывая, что все остальные прямые атрибуты тега manifest доступны из PackageInfo, я думаю, вы правы, что нужно искать его там.
Я знаю, что этого нет в документации, но вы все равно пробовали? Что-то вроде
PackageInfo pkg = ...;
String loc = pkg.installLocation();
Я знаю, что это, вероятно, очень наивно, учитывая, что документ может даже генерироваться автоматически - и я бы не осмелился предложить это, если бы мог попробовать сам (застрял на API 7 в настоящее время из-за отсталой ОС, которая больше не поддерживается в 8)
Если это не работает, я боюсь, что они просто упустили это из виду - я не могу себе представить, что они вдруг поместили бы это в другое место. В таком случае, вы, вероятно, застрянете, разбирая манифесты самостоятельно.