Comment vérifier si APK est signé ou "debug"?
autant que je sache, dans android" Release build " est signé APK. Comment le vérifier à partir du code ou est-ce que Eclipse a une sorte de définition secrète?
j'en ai besoin pour déboguer la saisie des éléments ListView à partir des données du service web (non, logcat n'est pas une option).
mes pensées:
- Application
android:debuggable
, mais pour une raison qui ne semble pas fiable. - ID de périphérique codant dur N'est pas une bonne idée, parce que j'utilise le même périphérique pour tester les APK signés.
- utilisant un drapeau manuel quelque part dans le code? Plausible, mais je vais oublier de changer à un moment donné, et tous les programmeurs sont paresseux.
9 réponses
il y a une façon différente de vérifier si l'application est construite en utilisant le certificat de débogage ou de publication, mais la façon suivante me semble la meilleure.
selon les informations dans la documentation Android Signing Your Application , debug key contain following subject distinguished name:" CN=Android Debug,O=Android,C=US ". Nous pouvons utiliser cette information pour tester si le paquet est signé avec la clé de débogage sans clé de débogage hardcoding. signature dans notre code.
:
import android.content.pm.Signature;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
vous pouvez implémenter une méthode isDebuggable de cette façon:
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;
}
pour vérifier le drapeau débuggable, vous pouvez utiliser ce code:
boolean isDebuggable = ( 0 != ( getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE ) );
pour plus d'informations, veuillez consulter sécuriser les Applications LVL Android .
Sinon, si vous utilisez Gradle correctement, vous pouvez vérifier si BuildConfig.DEBUG
est vrai ou faux.
, a Répondu par Mark Murphy
la solution la plus simple et la meilleure à long terme , est d'utiliser BuildConfig.DEBUG
. Il s'agit d'une valeur boolean
qui sera true
pour une construction de débogage, false
sinon:
if (BuildConfig.DEBUG) {
// do something for a debug build
}
si vous voulez vérifier un APK
de façon statique, vous pouvez utiliser
aapt dump badging /path/to/apk | grep -c application-debuggable
cette sortie 0
si la APK
n'est pas déboguable et 1
si elle l'est.
ajoutez D'abord ceci à votre construction.gradle file, ce qui permettra également d'exécuter côte à côte des compilations debug et release:
buildTypes {
debug {
applicationIdSuffix ".debug"
}
}
ajouter cette méthode:
public static boolean isDebug(Context context) {
String pName = context.getPackageName();
if (pName != null && pName.endsWith(".debug")) {
return true;
} else {
return false;
}
}
debug est signé ainsi, juste avec une clé différente. Il est généré automatiquement par Eclipse, et son certificat est valide pour un an seulement. Quel est le problème avec android:debuggable
? Vous pouvez obtenir cette valeur à partir du code en utilisant PackageManager
.
une autre option qui vaut la peine d'être mentionnée. Si vous avez besoin d'exécuter du code seulement lorsque le débogueur est attaché, utilisez ce code:
if (Debug.isDebuggerConnected() || Debug.waitingForDebugger()) {
//code to be executed
}
résolu par android:debuggable
. C'était un bug dans la lecture de l'élément où dans certains cas, le drapeau de débogage sur l'élément n'était pas stocké dans l'enregistrement if (m.debug && !App.isDebuggable(getContext()))
toujours évalué à false
. Mon mauvais.