如何检查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
。 我的错。