2010-06-17 3 views
6

Ich versuche, eine Android 2.2 App zu schreiben, die installierte Apps finden wird, die auf die SD-Karte verschoben werden können. Die Berechtigung dazu ist in der Datei AndroidManifest.xml als Root-Level-Attribut "android:installLocation" codiert. PackageInfo scheint eine Schnittstelle zu allem außer diesem Attribut zu haben. Ich kann die installierte apk öffnen und die AndroidManifest.xml-Datei extrahieren, aber es scheint in einem binären Kodierungsformat zu sein, für das einige zufällige Internet-Leute einen Decoder geschrieben haben, aber das scheint eine Menge Arbeit zu sein.Zugriff auf android: installLocation Manifestattribut

Gibt es eine Schnittstelle, die ich vermisse?

Antwort

12

Wie sich herausstellt, gibt es keinen direkten API-Aufruf, um installLocation zu bekommen, aber ich muss auch nicht das binäre XML manuell analysieren, da das mitgelieferte XmlResourceParser daran arbeitet.

// 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, ich denke, es gibt eine switch dort mit einem case, die wahrscheinlich nur ein if sein sollte. Naja. Sie bekommen den Punkt.

+0

Scheint relativ einfach - gut zu wissen! – Joubarc

0

Alle anderen direkten Attribute des Manifest-Tags sind von PackageInfo verfügbar. Ich denke, Sie haben Recht, danach zu suchen.

Ich weiß, dass es nicht im Doc ist, aber hast du es trotzdem versucht? So etwas wie

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

Ich weiß, das wahrscheinlich sehr naiv ist das doc auch unter Berücksichtigung automatisch generiert werden können - und ich würde es nicht wagen, vorschlagen, wenn ich es selbst versuchen könnte (klemmt auf API 7 im Moment aufgrund verzögert OS nicht mehr unterstützt in 8)

Wenn es nicht funktioniert, ich fürchte, sie haben nur übersehen, dass - ich kann mir nicht vorstellen, dass sie es plötzlich woanders setzen würde. In diesem Fall werden Sie wahrscheinlich die Manifeste wirklich selbst analysieren.

+0

eingeführt wurde, habe ich das versuchen, und es hat nicht funktioniert. – wfaulk

+0

Ja, zu viel Wunschdenken meinerseits nehme ich an. – Joubarc

0

In dem älteren APIs aus dem Jahr 2007 gab es öffentliche Felder in der Package Klasse, die alle Informationen über die internalLocation und andere relevante Informationen gab. Aus Sicherheitsgründen vermute ich, dass sie diese bequemen Felder losgeworden sind.

0

können Sie dieses Attribut zugreifen, indem Sie folgendes Beispiel:

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
in API 21

Aber dieses Feld existiert auch in Android 2,3 http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.3_r1/android/content/pm/PackageInfo.java/