¿Cómo comprobar si APK está firmado o "debug build"?

Por lo que sé, en android "release build" está firmado APK. ¿Cómo comprobarlo de código o Eclipse tiene algún tipo de secreto define?

Necesito esto para depurar los elementos ListView de los datos del servicio web (no, logcat no es una opción).

Mis pensamientos:

  • android:debuggable la aplicación android:debuggable , pero por alguna razón que no parece confiable.
  • ID de dispositivo de codificación no es una buena idea, porque estoy usando el mismo dispositivo para probar firmado APKs.
  • ¿Utilizar el indicador manual en algún lugar del código? Plausible, pero va a olvidar definitivamente de cambiar en algún momento, además de todos los programadores son perezosos.

Hay una manera diferente de comprobar si la aplicación se genera usando depuración o certificado de liberación, pero la siguiente manera me parece mejor.

De acuerdo con la información de la documentación de Android firmando su aplicación , la clave de depuración contiene el siguiente nombre distinguido del sujeto: " CN = Android Debug, O = Android, C = US ". Podemos usar esta información para probar si el paquete está firmado con la clave de depuración sin codificar la firma de la clave de depuración en nuestro código.

Dado:

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

Puede implementar un método isDebuggable de esta manera:

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

Para comprobar el indicador de depuración, puede utilizar este código:

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

Para obtener más información, consulte Cómo proteger las aplicaciones de Android LVL .

Como alternativa, si está utilizando Gradle correctamente, puede comprobar si BuildConfig.DEBUG es true o false.

Respuesta de Mark Murphy

La solución más simple y mejor a largo plazo es utilizar BuildConfig.DEBUG . Este es un valor boolean que será true para una compilación de depuración, false caso contrario:

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

Tal vez tarde, pero iosched utiliza BuildConfig.DEBUG

Si desea comprobar un APK forma estática, puede utilizar

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

Esto genera 0 si el APK no es debugable y 1 si lo es.

Primero agregue esto a su archivo build.gradle, esto también permitirá el funcionamiento lado a lado de las compilaciones de depuración y liberación:

 buildTypes { debug { applicationIdSuffix ".debug" } } 

Añada este método:

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

Una construcción de depuración también está firmada, sólo con una clave diferente. Se genera automáticamente por Eclipse, y su certificado es válido sólo por un año. ¿Cuál es el problema con android:debuggable ? Puede obtener este valor del código mediante PackageManager .

Otra opción, vale la pena mencionar. Si necesita ejecutar algún código sólo cuando se adjunta el depurador, utilice este código:
if (Debug.isDebuggerConnected() || Debug.waitingForDebugger()) { //code to be executed }

Resuelto con android:debuggable . Fue un fallo en la lectura del ítem donde en algunos casos el indicador de depuración en el elemento no estaba siendo almacenado en el registro if (m.debug && !App.isDebuggable(getContext())) obtuvo if (m.debug && !App.isDebuggable(getContext())) siempre evaluado a false . Mi error.

  • El dispositivo Android se desconecta del depurador unos segundos después de que se ha alcanzado el punto de interrupción
  • "Esperando que el depurador se adjunte" mostrando incluso cuando no se está ejecutando en modo de depuración
  • Aplicación de Android que carece de información de depuración en Android Studio
  • Error de depuración ADT20 NDK
  • Eclipse Android: No se pudo abrir el puerto de depuración de VM seleccionado (8700)
  • Depuración de aplicaciones nativas de Android NDK
  • El dispositivo Android se reinicia ocasionalmente
  • ¿Por qué no veo variables locales al depurar en Eclipse?
  • Pregunta sobre la seguridad del depurador
  • Android adb wireless / WIFI debug Operación agotada
  • Depuración después de reactivar una actividad
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.