如何检查是否APK进行签名或QUOT;调试版本"?版本、APK、QUOT

2023-09-12 06:53:04 作者:陌顏〆

据我所知,在Android的发行版本签署APK。如何检查它的从code 或做Eclipse有一些还挺秘密定义?

As far as I know, in android "release build" is signed APK. How to check it from code or does Eclipse has some kinda of secret defines?

我需要这个调试从Web服务数据(不,logcat的不是一个选项)填充的ListView项目。

I need this to debug populating ListView items from web service data (no, logcat not an option).

我的想法:

在应用程序的的android:可调试,但出于某种原因,看起来并不可靠。 硬编码设备ID是不是好主意,因为我用同样的设备进行测试签署的APK。 在code使用手动标记的地方?合理的,但绝对会忘了改,在一定的时间,再加上​​所有的程序员都很懒。 Application's android:debuggable, but for some reason that doesn't look reliable. Hard-coding device ID isn't good idea, because I am using same device for testing signed APKs. Using manual flag somewhere in code? Plausible, but gonna definitely forget to change at some time, plus all programmers are lazy.

推荐答案

有不同的方法来检查,如果应用程序是构建使用调试或释放证明,但下面的方式似乎最好的给我。

There are different way to check if the application is build using debug or release certificate, but the following way seems best to me.

据Android的文件签署您的应用程序,调试键包含以下主体的标识名称: CN = Android的调试,O =的Andr​​oid,C = US 。我们可以利用这些信息来测试封装与调试密钥签名没有硬编码调试的关键签名改成了code。

According to the info in Android documentation Signing Your Application, debug key contain following subject distinguished name: "CN=Android Debug,O=Android,C=US". We can use this information to test if package is signed with debug key without hardcoding debug key signature into our code.

由于:

import android.content.pm.Signature;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

您可以实现一个isDebuggable方法是这样的:

You can implement an isDebuggable method this way:

private static final X500Principal DEBUG_DN = new X500Principal("CN=Android Debug,O=Android,C=US");
private boolean isDebuggable(Context ctx)
{
    boolean debuggable = false;

    try
    {
        PackageInfo pinfo = ctx.getPackageManager().getPackageInfo(ctx.getPackageName(),PackageManager.GET_SIGNATURES);
        Signature signatures[] = pinfo.signatures;

        CertificateFactory cf = CertificateFactory.getInstance("X.509");

        for ( int i = 0; i < signatures.length;i++)
        {   
            ByteArrayInputStream stream = new ByteArrayInputStream(signatures[i].toByteArray());
            X509Certificate cert = (X509Certificate) cf.generateCertificate(stream);       
            debuggable = cert.getSubjectX500Principal().equals(DEBUG_DN);
            if (debuggable)
                break;
        }
    }
    catch (NameNotFoundException e)
    {
        //debuggable variable will remain false
    }
    catch (CertificateException e)
    {
        //debuggable variable will remain false
    }
    return debuggable;
}