首页 文章

如何检查APK是否已签名或“调试版本”?

提问于
浏览
112

据我所知,在android "release build"中签名APK . 如何检查 from code 或Eclipse是否有某种秘密定义?

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

我的想法:

  • 应用程序的 android:debuggable ,但由于某种原因看起来不可靠 .

  • 硬编码设备ID不是一个好主意,因为我使用相同的设备来测试签名的APK .

  • 在代码中的某处使用手动标志?合理,但肯定会在某个时候忘记改变,加上所有程序员都很懒惰 .

9 回答

  • 3

    如果要静态检查 APK ,可以使用

    aapt dump badging /path/to/apk | grep -c application-debuggable
    

    如果 APK 不可调试,则输出 0 ,如果是,则输出 1 .

  • 21

    Mark Murphy回答

    The simplest, and best long-term solution ,是使用 BuildConfig.DEBUG . 对于调试版本,这是一个 booleantrue ,否则为 false

    if (BuildConfig.DEBUG) {
      // do something for a debug build
    }
    
  • 132

    解决 android:debuggable . 这是在阅读项目中的错误,在某些情况下,项目上的调试标志没有被存储在记录中, if (m.debug && !App.isDebuggable(getContext())) 始终被评估为 false . 我的错 .

  • 5

    有不同的方法来检查应用程序是否使用调试或发布证书构建,但以下方式对我来说似乎是最好的 .

    根据Android文档Signing Your Application中的信息,调试密钥包含以下主题可分辨名称:“ CN=Android Debug,O=Android,C=US ” . 我们可以使用此信息来测试是否使用调试密钥对包进行签名,而无需将调试密钥签名硬编码到我们的代码中 .

    鉴于:

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

    您可以通过以下方式实现isDebuggable方法:

    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;
    }
    
  • 126

    也许迟到了,但iosched使用 BuildConfig.DEBUG

  • 0

    另一种选择,值得一提 . 如果只在附加调试器时需要执行某些代码,请使用以下代码:
    if (Debug.isDebuggerConnected() || Debug.waitingForDebugger()) { //code to be executed }

  • 75

    首先将它添加到build.gradle文件中,这也将允许并行运行调试和发布版本:

    buildTypes {
        debug {
            applicationIdSuffix ".debug"
        }
    }
    

    添加此方法:

    public static boolean isDebug(Context context) {
        String pName = context.getPackageName();
        if (pName != null && pName.endsWith(".debug")) {
            return true;
        } else {
            return false;
        }
    }
    
  • 10

    调试版本也会被签名,只需使用不同的密钥 . 它是 android:debuggable 的问题 android:debuggable ?您可以使用 PackageManager 从代码中获取此值 .

  • 16

    要检查debuggable标志,可以使用以下代码:

    boolean isDebuggable =  ( 0 != ( getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE ) );
    

    有关详细信息,请参阅Securing Android LVL Applications .

    或者,如果您正确使用Gradle,则可以检查 BuildConfig.DEBUG 是true还是false .

相关问题