2010-06-17 93 views
6

我試圖編寫一個Android 2.2應用程序,它會查找可以移動到SD卡上的已安裝的應用程序。執行此操作的權限將作爲根級屬性「android:installLocation」編碼在AndroidManifest.xml文件中。 PackageInfo似乎有一個接口,但除了這個屬性的所有內容。我可以打開已安裝的apk並提取AndroidManifest.xml文件,但它似乎是一些二進制編碼格式,一些隨機互聯網人員已經爲其編寫了解碼器,但這似乎是一項非常多的工作。訪問android:installLocation清單屬性

是否有我失蹤的界面?

回答

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 2010-07-11 19:09:35

0

考慮到清單標記的所有其他直接屬性都可以從PackageInfo中獲得,我認爲你在這裏找對了。

我知道它不在文檔中,但是您是否嘗試過?像

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

東西,我知道這可能是很幼稚考慮到醫生可能甚至可以自動生成 - 我不敢建議,如果我可以自己試試吧(貼在API 7此刻由於智障操作系統不再支持8)

如果它不起作用,恐怕他們忽略了 - 我無法想象他們會突然把它放在其他地方。在這種情況下,你可能會被卡在解析清單上。

+0

我做了嘗試,並沒有奏效。 – wfaulk 2010-06-19 15:01:38

+0

是的,我想我的想法太多了。 – Joubarc 2010-06-19 15:25:00

0

在2007年的舊API中,PackageInfo類中存在公有字段,它提供了有關internalLocation和其他相關信息的所有信息。出於安全原因,我猜測他們擺脫了那些方便的領域。

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/