2012-11-20 3 views
108

AndroidManifest.xmlファイルからダウンロードした後、インストールしないと、バージョンコードまたはapkのバージョン名をプログラムで取得する方法を教えてください。例えばAndroidの.apkファイルを取得するバージョン名またはバージョンコードapkをインストールしないで

<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="xxx.xx.xxx" 
    android:versionCode="1" 
    android:versionName="1.1" > 

私は、デバイス、そうでない場合は、私はそれをインストールしたくない新しいバージョンにインストールした後、新しいバージョンが私のIISサービスにアップロードされたかどうかを確認します。

+0

これを確認してください。http://stackoverflow.com/a/4761689/1109425 – nandeesh

+0

結局のところ何か分かりましたか?私は同じ問題に直面しています。ありがとう! – Mathieu

+0

ところで、誰も良い解決策はファイルをダウンロードして、それが必要かどうかをチェックすることだと誰も考えないことを願っています。代わりに、あなたのサーバー*上で実行されるコードを*必要とし、使用可能なバージョン番号で応答すると考えられます。 – ToolmakerSteve

答えて

4

これで、バイナリXMLデータからAPKファイルのバージョンを正常に取得できるようになりました。私は私の答えへの鍵を持ってどこ

このトピックでは、(私もリボのコードの私のバージョンを追加しました)です: How to parse the AndroidManifest.xml file inside an .apk package

はさらに、ここで私が書いたXML解析コードは、バージョンを取得するために具体的には、です:

このコードは、次のトピックからインスピレーションを得ている:(前のスニペットでSystemPackageTools.compareVersionsとして見られる)

/** 
* Verifies at Conductor APK path if package version if newer 
* 
* @return True if package found is newer, false otherwise 
*/ 
public static boolean checkIsNewVersion(String conductorApkPath) { 

    boolean newVersionExists = false; 

    // Decompress found APK's Manifest XML 
    // Source: https://stackoverflow.com/questions/2097813/how-to-parse-the-androidmanifest-xml-file-inside-an-apk-package/4761689#4761689 
    try { 

     if ((new File(conductorApkPath).exists())) { 

      JarFile jf = new JarFile(conductorApkPath); 
      InputStream is = jf.getInputStream(jf.getEntry("AndroidManifest.xml")); 
      byte[] xml = new byte[is.available()]; 
      int br = is.read(xml); 

      //Tree tr = TrunkFactory.newTree(); 
      String xmlResult = SystemPackageTools.decompressXML(xml); 
      //prt("XML\n"+tr.list()); 

      if (!xmlResult.isEmpty()) { 

       InputStream in = new ByteArrayInputStream(xmlResult.getBytes()); 

       // Source: http://developer.android.com/training/basics/network-ops/xml.html 
       XmlPullParser parser = Xml.newPullParser(); 
       parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false); 

       parser.setInput(in, null); 
       parser.nextTag(); 

       String name = parser.getName(); 
       if (name.equalsIgnoreCase("Manifest")) { 

        String pakVersion = parser.getAttributeValue(null, "versionName"); 
          //NOTE: This is specific to my project. Replace with whatever is relevant on your side to fetch your project's version 
        String curVersion = SharedData.getPlayerVersion(); 

        int isNewer = SystemPackageTools.compareVersions(pakVersion, curVersion); 

        newVersionExists = (isNewer == 1); 
       } 

      } 
     } 

    } catch (Exception ex) { 
     android.util.Log.e(TAG, "getIntents, ex: "+ex); 
     ex.printStackTrace(); 
    } 

    return newVersionExists; 
} 

バージョン比較 NOTEの解析

XML Efficient way to compare version strings in Java

/** 
* Compare 2 version strings and tell if the first is higher, equal or lower 
* Source: https://stackoverflow.com/questions/6701948/efficient-way-to-compare-version-strings-in-java 
* 
* @param ver1 Reference version 
* @param ver2 Comparison version 
* 
* @return 1 if ver1 is higher, 0 if equal, -1 if ver1 is lower 
*/ 
public static final int compareVersions(String ver1, String ver2) { 

    String[] vals1 = ver1.split("\\."); 
    String[] vals2 = ver2.split("\\."); 
    int i=0; 
    while(i<vals1.length&&i<vals2.length&&vals1[i].equals(vals2[i])) { 
     i++; 
    } 

    if (i<vals1.length&&i<vals2.length) { 
     int diff = Integer.valueOf(vals1[i]).compareTo(Integer.valueOf(vals2[i])); 
     return diff<0?-1:diff==0?0:1; 
    } 

    return vals1.length<vals2.length?-1:vals1.length==vals2.length?0:1; 
} 

これが役立ちます。

+0

コードが縮小されて見えるのはなぜですか? – forresthopkinsa

+0

新しいGradleまたはAndroid Studioにアップグレードしましたか?これはまだ機能しますか? RobioのコードはXMLの解凍にはもう役に立たない。 –

67
final PackageManager pm = getPackageManager(); 
String apkName = "example.apk"; 
String fullPath = Environment.getExternalStorageDirectory() + "/" + apkName;   
PackageInfo info = pm.getPackageArchiveInfo(fullPath, 0); 
Toast.makeText(this, "VersionCode : " + info.versionCode + ", VersionName : " + info.versionName , Toast.LENGTH_LONG).show(); 
+7

これは最善の回答であり、受け入れられるはずです。 –

+1

これは私のためには役に立たなかった – gian1200

+3

**アプリケーションをインストールせずに 'apk'コンテンツ**を読むにはどうすればいいですか? @PatrickCho – talha06

279

コマンドラインから私のために働いた後:

aapt dump badging myapp.apk 

注:aapt.exeは、SDKのbuild-toolsサブフォルダに含まれています。たとえば:

<sdk_path>/build-tools/23.0.2/aapt.exe 
+0

これは完璧に機能し、非常に簡単な解決策でした。ありがとう! – NateJC

+21

うまく動作します。これは正しい答えとしてマークする必要があります。情報は 'aapt'がsdkの* build-tools/XX *にあります。 –

+0

はツールやプラットフォームツールのaaptコマンドの一部ですか? – gmuhammad

3
EditText ET1 = (EditText) findViewById(R.id.editText1); 

    PackageInfo pinfo; 
    try { 
     pinfo = getPackageManager().getPackageInfo(getPackageName(), 0); 
     String versionName = pinfo.versionName; 
     ET1.setText(versionName); 
     //ET2.setText(versionNumber); 
    } catch (NameNotFoundException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
+5

これは質問に対する答えではありません。これは、実行中のアプリケーション内で、いくつかのバージョン情報を取得して表示するコードです。問題は、app *をインストールせずにAPKファイル*からこの情報を取得する方法です。 – ToolmakerSteve

2

アップグレードシナリオのために特別に別のアプローチは、現在のバージョン番号を提供するWebサービスを持っているだけでそのバージョンを確認するために全体のapkをダウンロードするのではなく、それをチェックすることであるかもしれません。帯域幅を節約し、パフォーマンスを少し向上させることができます(apk全体をほとんど必要としない場合はapkよりもはるかに高速でダウンロードできます)。実装するのがはるかに簡単です。そして、あなたは、サーバー上の単純なテキストファイルを持っている可能性が最も簡単な形式で

...そのテキストファイルの内部http://some-place.com/current-app-version.txt

3.1.4 

のようなものを持っていると、そのファイルをダウンロードしてに対してチェック現在インストールされているバージョン。あなたはバージョン2を使用している場合

{ 
    "current_version": "3.1.4" 
} 
+0

あなたは正しい方向にあります。バージョンを取得するだけでファイルをダウンロードすべきではありません。手動でテキストファイルを作成することはお勧めできません。実際のapkファイルと一致しないようにするにはあまりにも簡単です。代わりに、あなたが議論する手段で取得されるように、apkを見てそのバージョンが何であるかを見て、それをファイルやデータベースに保存するスクリプト(他の回答の1つを使用する)を書いてください。 – ToolmakerSteve

+0

このシナリオでは、APKとの一致が必要な場合ではなく、最新のバージョン番号が公開されている場合のみです。 – grego

24

:それより高度なソリューションを構築

は、適切なWebサービスを実装し、いくつかのJSONを返すことができます起動時にAPIコール、すなわちhttp://api.some-place.com/versionCheckを持っていることであろう。2以上Androidスタジオ次にAndroidスタジオで使用ビルドを分析してAPKを選択し、AndroidManifest.xmlファイルを選択します。

+2

OPはそれを「プログラムで」得る方法を尋ねた – forresthopkinsa

+1

彼はこのようなツールがAndroid Studioに組み込まれていることを知らなかったので。彼はまた、apk *をインストールせずに*尋ねました。 – vovahost

+1

もちろん、彼はそれを知らなかった。なぜなら、この質問が出されたときにAndroid Studioは存在しなかったからだ。さらに、たとえそれがあっても、これは彼の問題を解決することはできません - 彼は彼の質問に述べたように、彼のデバイスがプログラムで*自分のIISサーバーからの更新をチェックすることを望んでいます。 Patrick Choの答えは、インストールせずにプログラムで行う方法について説明しています。 – forresthopkinsa

関連する問題