如何检查APK是否签名或“debugging构build”?

据我所知,在Android“发布版本”是有签名的APK。 如何从代码检查它或Eclipse有一些秘密定义?

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

我的想法:

  • 应用程序的android:debuggable ,但由于某些原因,看起来不可靠。
  • 硬编码设备ID不是个好主意,因为我正在使用相同的设备来testing已签名的APK。
  • 在代码中的某处使用手动标志? 合理的,但一定会忘记改变,再加上所有的程序员都懒惰。

有不同的方法来检查应用程序是使用debugging还是发布证书来构build,但下面的方法对我来说似乎是最好的。

根据Android文档签名应用程序中的信息 ,debugging密钥包含以下主题专有名称:“ CN = Android Debug,O = Android,C = US ”。 我们可以使用这些信息来testing包是否用debugging密钥签名,而不用硬编码debugging密钥签名到我们的代码中。

鉴于:

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

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

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

有关更多信息,请参阅保护Android LVL应用程序 。

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

Mark Murphy回答

最简单和最好的长期解决scheme是使用BuildConfig.DEBUG 。 这是一个boolean值,对于debugging版本将是true ,否则为false

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

也许晚了,但是iosched使用BuildConfig.DEBUG

如果你想静态检查一个APK ,你可以使用

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

如果APK不可debugging,则输出0如果不是,则输出1

首先把这个添加到你的build.gradle文件中,这也将允许并排运行debugging和发布版本:

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

debugging版本也被签名,只是一个不同的密钥。 它是由Eclipse自动生成的,其证书仅在一年内有效。 android:debuggable什么问题? 你可以使用PackageManager从代码中获得这个值。

另一个select,值得一提。 如果只有在连接了debugging器时才需要执行一些代码,请使用以下代码:
if (Debug.isDebuggerConnected() || Debug.waitingForDebugger()) { //code to be executed }

android:debuggable解决。 这是读取项目中的错误,在某些情况下,debugging标志项目不被存储在logging中, if (m.debug && !App.isDebuggable(getContext()))总是计算为false 。 我的错。