2011-12-27 84 views
2

用例就是這樣。我爲企業編寫定製應用程序。這些應用程序是專有的,由於各種原因不適合Android Market。某些客戶要求應用程序定期自動聯繫公司服務器以檢查更新,並在需要時自動下載並安裝它們。我有一個這樣做的工作機制,但它不像我想的那樣健壯。最好的解決方案是在設備上運行應用程序,將其Android版本代碼(可能是VersionName)傳遞到服務器,在服務器上將這些代碼與服務器上潛在的升級.apk版本代碼進行比較。只有當服務器上的.apk代表升級時,它纔會上傳到設備並安裝。如何從Android環境以外的.apk文件中獲取Android versionCode&versionName?

發佈了很多建議的解決方案。一個常見的方法是在包含versionCode和versionName的服務器上放置一個單獨的文本文件,但可能會通過管理錯誤使該文本文件與.apk文件中的值不同步。結果將是不斷下載和不必要的下載。其他各種解決方案,例如使用apktool或其任何包裝器,雖然可行,但還有其他缺點。

我正在尋求解決方法,但似乎都涉及持續關於最近下載和安裝的.apk文件(例如校驗和)的一些附加信息。這些信息可以傳遞給服務器並進行比較。這可以起作用,但它不是我想要的那麼幹淨。

我正在尋找一個庫.jar文件,該文件將允許從.apk文件中提取versionCode和versionName。基本上會傳遞代表.apk文件位置的File對象,並提供獲取versionCode和versionName的方法。

其他建議將受到歡迎。

回答

0

我找到了一種方法來做到這一點,但不是因爲心裏暗淡。我下載了AXMLPrinter2.jar這是一個自包含的.jar文件,可用於讀取,解釋和展開android.XML文件的內容。特別是,它以可讀的格式顯示AndroidManifest.xml的內容。不過,我需要通過編程訪問AndroidManifest.xml的內容。

這是它變得有趣的地方。

我首先提取了AXMLPrinter2.jar中的MANIFEST.XML文件以查找主類,即AXMLPrinter。

然後,我對AXMLPrinter.class進行了反編譯,結果是AXMLPrinter2.jar中包含的AXML解析器的相對簡單的包裝,並且派生了一個名爲ReadAndroidManifest的新類。由於這個類是用於服務器的,所以它有一個簡單的構造函數ReadAndroidManifest(File apkFile),並提供了兩個方法:getVersionCode()和getVersionName()。

我簡單地將AXMLPrinter2.jar文件添加到我的Web應用程序庫(未修改!),並將派生類ReadAndroidManifest包括在確定apk文件是否代表升級的servlet部分中。

顯然,這種技術可以通過更一般的方式擴展來提供對AndroidManifest.xml文件的所有元素的訪問,但上面的簡單版本完全適合我的目的。

0

我很喜歡爲同樣的事情工作,並通過閱讀這麼多帖子後,我進入了一種解決方法,我認爲這是從APK通過純JAVA代碼geting packageName和版本的最舒適的方式(out of Android環境)。

首先,我已經donwloaded apktool。如果鏈接由於某種原因未能正常工作,則爲apktool,其名稱爲apktool依賴關係和助手腳本,用於下載頁面下的windows。然後,我解壓縮文件夾並獲得其aapt.exe,放入我的java項目文件夾。

然後,我的Java代碼中,我只是寫這樣:

ProcessBuilder builder = new ProcessBuilder("PATH_TO_APKTOOL_AAPT.exe", "dump", "badging", "path_to_your_apk_file"); 
Process p; 
String output = ""; 
try { 
p = builder.start(); 
BufferedReader r = new BufferedReader(new InputStreamReader(p.getInputStream())); 
    String line; 
    while (true) { 
    line = r.readLine(); 
     if (line == null) { break; } 
    output += line; 
    } 
     Pattern pattern = Pattern.compile("package: name='(.*?)'", Pattern.CASE_INSENSITIVE); 
     Matcher m = pattern.matcher(output);    
     m.find(); 
    System.out.println("package name:" + m.group(1).trim()); 
    pattern = Pattern.compile("package:.*?versionCode='(.*?)'", Pattern.CASE_INSENSITIVE); 
    m = pattern.matcher(output); 
    m.find(); 
    System.out.println("version:" + m.group(1).trim()); 
} catch (IOException e) { 
    e.printStackTrace(); 
} 

`

嗯,這是一種較少副作用和獲取APK包名稱和版本的簡單方法代碼:)

相關問題