簡體   English   中英

通過代碼檢測應用是否為生產/發布版本

[英]Detect if App is Production/Release Version from Code

我的應用程序中有一個自制的日志記錄系統。 它所做的事情是在開發過程中預先執行許多日志記錄(到文件和logcat),並且可以通過一次可變更改將其完全關閉。 有關功能示例:

static public  final boolean DEVELOPMENT_VERBOSE = true;

public static void developmentLogMessage(String message) {
    if (DEVELOPMENT_VERBOSE)
        Log.i("com.xxx.app",  message);
}

我遇到的問題(可能更煩人)是,我必須記住要設置DEVELOPMENT_VERBOSE = false才能發布。 代碼中是否有辦法檢測應用程序何時最終發布(例如檢查簽名的apk),以便我可以通過編程將DEVELOPMENT_VERBOSE設置為false

我查看了“ 檢測是否從Android Market下載了應用程序”,但似乎我的應用程序甚至在為市場簽名之前就已經簽名。

try {
    PackageManager manager = context.getPackageManager(); 
    PackageInfo appInfo = manager.getPackageInfo(
                    "com.xxx.app", PackageManager.GET_SIGNATURES
        );

    System.out.println(appInfo.signatures[0].toCharsString());
} catch (NameNotFoundException e) {
}

我希望簽名數組為空,並且可以輸入其中的鍵。 但是不行。

構建發行版時,可以使用ProGuard完全關閉適當的日志。 ProGuard可以做很多有趣的事情。 它可以在構建過程中收縮不需要的代碼。 例如,如果在開發過程中使用調試日志(Log.d()),但要在發行版中禁用它,則可以將以下幾行添加到proguard.cfg中:

-assumenosideeffects class android.util.Log {
  public static int d(...);
}

要啟用ProGuard,請設置屬性

proguard.config=proguard.cfg

到您的project.properties (如果使用默認位置)。 請注意,ProGuard默認情況下還會執行其他一些操作,因此在發布項目時,您可能應該采取一些其他步驟。 至少您肯定要保存生成的mapping.txt文件。 有關更多詳細信息,請參見ProGuard指南

您可以查看使用哪個證書對應用程序進行簽名,並采取相應的措施。

例如:

  for (Signature sig : getPackageManager().getPackageInfo(getPackageName(), PackageManager.GET_SIGNATURES).signatures) {
    // Get some (pseudo)uniqe value:
    long sigHash = Arrays.hashCode(sig.toByteArray());
    if (sigHash == releaseSigHash) DEVELOPMENT_VERBOSE = false;
  }

這是我對Google MapView所做的事情,以確定要使用哪個API密鑰,這是一個類似的問題

  for (Signature sig : getPackageManager().getPackageInfo(getPackageName(), PackageManager.GET_SIGNATURES).signatures) {
    MessageDigest m = MessageDigest.getInstance("MD5");
    m.update(sig.toByteArray());
    md5 = new BigInteger(1, m.digest()).toString(16);

    Log.d("findApiNøgle", "md5fingerprint: "+md5);

    // Jacobs debug-nøgle
    if (md5.equals("5fb3a9c4a1ebb853254fa1aebc37a89b")) return "0osb1BfVdrk1u8XJFAcAD0tA5hvcMFVbzInEgNQ";
    // Jacobs officielle nøgle
    if (md5.equals("d9a7385fd19107698149b7576fcb8b29")) return "0osb1BfVdrk3etct3WjSX-gUUayztcGvB51EMwg";

    // indsæt din egen nøgle her:
  }

經過一些研究/工作,我們可以提供一種解決方案,該解決方案可以根據所簽證書進行檢查。

        static public boolean DEVELOPMENT_VERBOSE = false;
        static private final  X500Principal RELEASE_DN = new X500Principal(
            "CN=aaa,OU=bbb,O=ccc,L=ddd,ST=eee,C=fff"
            );

        // auto disable the development logs if the apk is signed with a cert
        try {
            PackageManager manager = context.getPackageManager();
            PackageInfo appInfo = manager.getPackageInfo("com.xxx.app",
                    PackageManager.GET_SIGNATURES);
            Signature raw = appInfo.signatures[0];

            try {
                CertificateFactory cf = CertificateFactory.getInstance("X.509");
                X509Certificate cert = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(raw.toByteArray()));

                //DEVELOPMENT_VERBOSE = cert.getSubjectX500Principal().equals(DEBUG_DN);
                if (!cert.getSubjectX500Principal().equals(RELEASE_DN))
                    DEVELOPMENT_VERBOSE = true;

            } catch (CertificateException e) {  

            }           
        } catch (NameNotFoundException e) {

        }

只要您在應用的版本之間使用相同的證書,該證書將始終有效。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM