Как проверить, подписана ли APK или «отладить сборку»?

Насколько мне известно, в андроиде «релиз сборка» подписали APK. Как проверить это из кода или определяет ли Eclipse какой-то секрет?

Мне нужно это для отладки заполнения элементов ListView из данных веб-службы (нет, logcat не опция).

Мои мысли:

  • android:debuggable приложения android:debuggable , но по какой-то причине он не выглядит надежным.
  • Идентификатор устройства с жестким кодированием не является хорошей идеей, потому что я использую одно и то же устройство для тестирования подписанных APK.
  • Использовать флаг вручную где-нибудь в коде? Правдоподобно, но определенно забудьте изменить в какое-то время, плюс все программисты ленивы.

Есть другой способ проверить, работает ли приложение с использованием сертификата отладки или выпуска, но для меня это выглядит лучше всего.

Согласно информации в документации Android для подписи вашего приложения , ключ отладки содержит следующее имя различающегося характера: « CN = Android Debug, O = Android, C = US ». Мы можем использовать эту информацию, чтобы проверить, подписан ли пакет с помощью отладочного ключа без подписи ключевого слова hardcoding в нашем коде.

Данный:

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

Чтобы проверить флаг отладки, вы можете использовать этот код:

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

Дополнительную информацию см. В разделе Защита приложений Android LVL .

Кроме того, если вы правильно используете Gradle, вы можете проверить, является ли BuildConfig.DEBUG истинным или ложным.

Ответа на этот вопрос Mark Murphy

Самое простое и лучшее долгосрочное решение – использовать BuildConfig.DEBUG . Это boolean значение, которое будет 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 

Это выводит 0 если APK не отлаживается и 1 если он есть.

Сначала добавьте это в свой файл build.gradle, это также позволит работать с отладочными и релизными сборками:

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

Отладочная сборка также подписана, просто с другим ключом. Он автоматически генерируется Eclipse, и его сертификат действителен только один год. В чем проблема с android:debuggable ? Вы можете получить это значение из кода с помощью PackageManager .

Еще один вариант, заслуживающий упоминания. Если вам нужно выполнить какой-либо код только при подключении отладчика, используйте этот код:
if (Debug.isDebuggerConnected() || Debug.waitingForDebugger()) { //code to be executed }

Решено с android:debuggable . Это была ошибка при чтении элемента, где в некоторых случаях флаг отладки на элементе не сохранялся в записи, if (m.debug && !App.isDebuggable(getContext())) всегда оценивается как false . Виноват.