2010-06-17 4 views
6

Я пытаюсь написать приложение Android 2.2, которое найдет установленные приложения, которые можно перенести на SD-карту. Разрешение сделать это закодировано в файле AndroidManifest.xml как атрибут корневого уровня «android:installLocation». PackageInfo, похоже, имеет интерфейс ко всему, кроме этого атрибута. Я могу открыть установленный apk и извлечь файл AndroidManifest.xml, но, похоже, он находится в некотором бинарном формате кодирования, который некоторые случайные пользователи Интернета написали декодер, но это похоже на ужасную работу.Доступ к андроиду: installLocation manifest attribute

Есть ли интерфейс, который мне не хватает?

ответ

12

Как оказалось, пока нет прямого вызова 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(); 
    } 

Ну, я думаю, есть switch там с одним case, что, вероятно, следует просто быть if. Ну что ж. Вы понимаете.

+0

Кажется, относительно легко - хорошо знать! – Joubarc

0

Учитывая все другие прямые атрибуты тега манифеста, можно получить в PackageInfo, я думаю, что вы правы, чтобы искать его там.

Я знаю, что это не в документе, но вы все равно пробовали? Что-то вроде

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

Я знаю, что это, вероятно, очень наивно рассматривает документ может даже быть сгенерирован автоматически - и я бы не рискнул предположить, если бы я мог попробовать себя (застрял на API 7 на данный момент из-за отсталый OS больше не поддерживается в 8)

Если это не сработает, я боюсь, что они просто не обратили внимания на это - я не могу представить, чтобы они внезапно поместили его в другое место. В этом случае вы, вероятно, застрянете в синтаксическом разборе манифестаций.

+0

Я попробовать это, и это не сработало. – wfaulk

+0

Да, слишком много желаемого за действительное с моей стороны, я полагаю. – Joubarc

0

В старых API от 2007 года в классе PackageInfo были открыты общедоступные поля, которые предоставили всю информацию о внутренней локации и другую соответствующую информацию. По соображениям безопасности я предполагаю, что они избавились от этих удобных полей.

0

Вы можете получить доступ к этому атрибуту в следующем примере:

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

http://developer.android.com/reference/android/content/pm/PackageInfo.html#installLocation
был введен в API 21

Но это поле существует даже в Android 2.3 http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.3_r1/android/content/pm/PackageInfo.java/

Смежные вопросы