¿Cómo verificar si APK está firmado o “depurar comstackción”?

Por lo que sé, en Android “versión de lanzamiento” está firmado APK. ¿Cómo verificarlo desde el código o Eclipse tiene algún tipo de definiciones secretas?

Necesito esto para depurar los elementos de 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 no parece confiable.
  • La identificación del dispositivo de encoding dura no es una buena idea, porque estoy usando el mismo dispositivo para probar APK firmados.
  • ¿Usando la bandera manual en alguna parte del código? Plausible, pero definitivamente se olvidará de cambiar en algún momento, además todos los progtwigdores son flojos.

Hay una forma diferente de verificar si la aplicación está comstackda usando un certificado de depuración o versión, pero la mejor manera para mí es la siguiente.

De acuerdo con la información en la documentación de Android firmando su aplicación , la clave de depuración contiene el siguiente nombre distinguido: ” CN = Android Debug, O = Android, C = US “. Podemos utilizar esta información para probar si el paquete está firmado con la clave de depuración sin hardcoding la firma de 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 verificar el indicador de depuración, puede usar este código:

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

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

Alternativamente, si está utilizando Gradle correctamente, puede verificar si BuildConfig.DEBUG es verdadero o falso.

Respondido por Mark Murphy

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

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

Quizás tarde, pero iosched usa BuildConfig.DEBUG

Si desea verificar una APK estáticamente, puede usar

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

Esto produce 0 si el APK no es depurable y 1 si lo es.

Primero, agregue esto a su archivo build.gradle, esto también permitirá que se ejecuten lado a lado las versiones de depuración y liberación:

 buildTypes { debug { applicationIdSuffix ".debug" } } 

Agrega este método:

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

También se firma una comstackción de depuración, solo con una clave diferente. Eclipse lo genera automáticamente y su certificado es válido solo por un año. ¿Cuál es el problema con android:debuggable ? Puede obtener este valor del código usando PackageManager .

Otra opción, vale la pena mencionar. Si necesita ejecutar algún código solo cuando está conectado un depurador, use este código:
if (Debug.isDebuggerConnected() || Debug.waitingForDebugger()) { //code to be executed }

Resuelto con android:debuggable . Era un error al leer el artículo, en el que en algunos casos, el indicador de depuración del elemento no se almacenaba en el registro obteniendo if (m.debug && !App.isDebuggable(getContext())) siempre evaluado como false . Mi error.