简体   繁体   English

通过代码检测应用是否为生产/发布版本

[英]Detect if App is Production/Release Version from Code

I have a home made logging system in my app. 我的应用程序中有一个自制的日志记录系统。 Of the things that it does is preform alot of logging (to file and logcat) while in development and can be turned off completely with one varible change. 它所做的事情是在开发过程中预先执行许多日志记录(到文件和logcat),并且可以通过一次可变更改将其完全关闭。 For a functionality example: 有关功能示例:

static public  final boolean DEVELOPMENT_VERBOSE = true;

public static void developmentLogMessage(String message) {
    if (DEVELOPMENT_VERBOSE)
        Log.i("com.xxx.app",  message);
}

The problem (maybe more an annoyance) I have is that I must remember to set DEVELOPMENT_VERBOSE = false for release. 我遇到的问题(可能更烦人)是,我必须记住要设置DEVELOPMENT_VERBOSE = false才能发布。 Is there a way in code to detect when the app is finalized for release (say checking for a signed apk for example) so I can set DEVELOPMENT_VERBOSE to false programmatically? 代码中是否有办法检测应用程序何时最终发布(例如检查签名的apk),以便我可以通过编程将DEVELOPMENT_VERBOSE设置为false

I looked at Detect if app was downloaded from Android Market but it seems my app has a signature even before signing it for the market. 我查看了“ 检测是否从Android Market下载了应用程序”,但似乎我的应用程序甚至在为市场签名之前就已经签名。

try {
    PackageManager manager = context.getPackageManager(); 
    PackageInfo appInfo = manager.getPackageInfo(
                    "com.xxx.app", PackageManager.GET_SIGNATURES
        );

    System.out.println(appInfo.signatures[0].toCharsString());
} catch (NameNotFoundException e) {
}

I was hoping the signatures array would be empty and I could key of of that. 我希望签名数组为空,并且可以输入其中的键。 But no go. 但是不行。

You can use ProGuard to completely turn appropriate logs off when building a release. 构建发行版时,可以使用ProGuard完全关闭适当的日志。 ProGuard can do a lot of interesting stuff. ProGuard可以做很多有趣的事情。 Among other things it can shrink unneeded code during the building process. 它可以在构建过程中收缩不需要的代码。 For example, if you use debug log (Log.d()) during development, but want to disable it in release then you can add these lines to your proguard.cfg: 例如,如果在开发过程中使用调试日志(Log.d()),但要在发行版中禁用它,则可以将以下几行添加到proguard.cfg中:

-assumenosideeffects class android.util.Log {
  public static int d(...);
}

To enable ProGuard, set the property 要启用ProGuard,请设置属性

proguard.config=proguard.cfg

to your project.properties (if you use default locations). 到您的project.properties (如果使用默认位置)。 Be noted that ProGuard will also do some other things by default so you probably should take some additional steps when releasing your project. 请注意,ProGuard默认情况下还会执行其他一些操作,因此在发布项目时,您可能应该采取一些其他步骤。 At least you certainly want to save generated mapping.txt file. 至少您肯定要保存生成的mapping.txt文件。 See the ProGuard guide for more details. 有关更多详细信息,请参见ProGuard指南

You can look at which certificate was used to sign the app, and act accordingly. 您可以查看使用哪个证书对应用程序进行签名,并采取相应的措施。

For example: 例如:

  for (Signature sig : getPackageManager().getPackageInfo(getPackageName(), PackageManager.GET_SIGNATURES).signatures) {
    // Get some (pseudo)uniqe value:
    long sigHash = Arrays.hashCode(sig.toByteArray());
    if (sigHash == releaseSigHash) DEVELOPMENT_VERBOSE = false;
  }

Here is what I do for Google MapView, to decide which API Key to use, which is a similar problem 这是我对Google MapView所做的事情,以确定要使用哪个API密钥,这是一个类似的问题

  for (Signature sig : getPackageManager().getPackageInfo(getPackageName(), PackageManager.GET_SIGNATURES).signatures) {
    MessageDigest m = MessageDigest.getInstance("MD5");
    m.update(sig.toByteArray());
    md5 = new BigInteger(1, m.digest()).toString(16);

    Log.d("findApiNøgle", "md5fingerprint: "+md5);

    // Jacobs debug-nøgle
    if (md5.equals("5fb3a9c4a1ebb853254fa1aebc37a89b")) return "0osb1BfVdrk1u8XJFAcAD0tA5hvcMFVbzInEgNQ";
    // Jacobs officielle nøgle
    if (md5.equals("d9a7385fd19107698149b7576fcb8b29")) return "0osb1BfVdrk3etct3WjSX-gUUayztcGvB51EMwg";

    // indsæt din egen nøgle her:
  }

After some research/work we can up with a solution that checks against the singed cert. 经过一些研究/工作,我们可以提供一种解决方案,该解决方案可以根据所签证书进行检查。

        static public boolean DEVELOPMENT_VERBOSE = false;
        static private final  X500Principal RELEASE_DN = new X500Principal(
            "CN=aaa,OU=bbb,O=ccc,L=ddd,ST=eee,C=fff"
            );

        // auto disable the development logs if the apk is signed with a cert
        try {
            PackageManager manager = context.getPackageManager();
            PackageInfo appInfo = manager.getPackageInfo("com.xxx.app",
                    PackageManager.GET_SIGNATURES);
            Signature raw = appInfo.signatures[0];

            try {
                CertificateFactory cf = CertificateFactory.getInstance("X.509");
                X509Certificate cert = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(raw.toByteArray()));

                //DEVELOPMENT_VERBOSE = cert.getSubjectX500Principal().equals(DEBUG_DN);
                if (!cert.getSubjectX500Principal().equals(RELEASE_DN))
                    DEVELOPMENT_VERBOSE = true;

            } catch (CertificateException e) {  

            }           
        } catch (NameNotFoundException e) {

        }

As long as you use the same cert from version to version of the app this will always work. 只要您在应用的版本之间使用相同的证书,该证书将始终有效。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 当版本代码似乎高于生产时,“被生产取代”会阻止测试 Android Xamarin 应用程序的 Alpha 版本 - "Superseded by production" prevents testing of Alpha release of Android Xamarin app when version code appears to be higher than production 是否可以检测到 android 应用程序是测试版还是生产版? - Is it possible to detect that an android app is either a beta version or production version? 在Android应用发布版本中获取错误的版本代码和版本名称 - Getting wrong version code and version name in android app release version Android应用程式的Beta / Production和Alpha版本码不同 - Android app different version code for beta/production and alpha 发布版本的不同版本代码 - Different version code for release version android:从应用程序代码中检测应用程序的重新安装 - android : detect the reinstall of an app from the app code 检测 App android 是否处于 Debug 或 Release - Detect if the App android is in Debug or Release 一个应用程序的开发和生产版本 - development and production version of one app Android AppLinks是否需要App的正式版? - Do Android AppLinks require a production release of App? 仅在生产版本中对应用程序加载RuntimeException - RuntimeException on app load only in production release
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM