2010-06-17 15 views
6

Sto provando a scrivere un'app Android 2.2 che troverà app installate che possono essere spostate sulla scheda SD. Il permesso per farlo è codificato nel file AndroidManifest.xml come attributo a livello di radice "android:installLocation". PackageInfo sembra avere un'interfaccia per tutto tranne questo attributo. Posso aprire l'apk installato ed estrarre il file AndroidManifest.xml, ma sembra che si trovi in ​​un formato di codifica binaria, che alcuni utenti di internet casuali hanno scritto per un decoder, ma sembra un sacco di lavoro.Accesso a android: attributo manifest di installazioneLink

C'è un'interfaccia che mi manca?

risposta

12

Come risulta, anche se non c'è una chiamata API diretta per ottenere installLocation, non è necessario analizzare manualmente l'XML binario, poiché lo strumento fornito è 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(); 
    } 

Uh, credo che ci sia un switch in là con un case che dovrebbe probabilmente essere solo un if. Oh bene. Ottieni il punto.

+0

Sembra abbastanza facile - buono a sapersi! – Joubarc

0

Considerando tutti gli altri attributi diretti del tag manifest sono disponibili da PackageInfo, penso che sia giusto cercarlo lì.

So che non è nel documento, ma ci hai provato lo stesso? Qualcosa di simile

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

So che questo è probabilmente molto ingenuo considerando il documento può anche essere generato automaticamente - e non oserei suggerire se ho potuto provare io stesso (bloccato su API 7 in questo momento a causa di ritardati Il sistema operativo non è più supportato in 8)

Se non funziona, temo che abbiano semplicemente trascurato questo: non riesco a immaginare che l'avrebbero messo altrove all'improvviso. In tal caso, probabilmente sarai bloccato a analizzare i manifesti da solo.

+0

Ho provato che, e non ha funzionato. – wfaulk

+0

Sì, troppo pio desiderio da parte mia, suppongo. – Joubarc

0

Nelle API precedenti del 2007, esistevano campi pubblici nella classe PackageInfo che fornivano tutte le informazioni sulla posizione interna e altre informazioni pertinenti. Per motivi di sicurezza, suppongo che si siano sbarazzati di quei campi convenienti.

0

Si può accedere a questo attributo esempio successivo:

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
è stato introdotto nel API 21

Ma questo campo esiste anche 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/

Problemi correlati