【问题标题】:package conflicts with an existing package by the same name包与同名的现有包冲突
【发布时间】:2017-04-07 12:41:53
【问题描述】:

由于上述消息,我的 apk 升级无法安装。

我读过 SO 上的帖子,说当应用使用不同的发布密钥签名时会出现此消息。

example post on different keys

。 在我的日志中,当我尝试升级 apk 时,我得到以下信息:

04-07 13:28:03.796 2072-2072/? W/InstallAppProgress: Replacing package:com.xxx.rr3

04-07 13:28:04.326 3675-3845/? W/PackageManager: verifying app can be installed or not

04-07 13:28:04.378 3675-3845/? W/PackageManager: Package com.xxx.rr3 signatures do not match the previously installed version; ignoring!

。 原始应用程序已经投入生产超过 4 年,是使用 Eclipse 编写的,它安装在我的旧硬盘上。

6 个月前,我的老板给我买了一个 SSD 驱动器,我安装了 Android Studio。我迁移了旧项目,它构建得很好,它会安装到没有安装以前版本的设备上。

我将密钥库从旧硬盘复制到新 SSD,并使用它在 Android Studio 中签署新版本的应用程序。所以我只使用过一个相同的密钥库,具有相同的密码和别名。

谁能告诉我为什么 Android 说我的升级是用不同的密钥签名的?

[更新1]

我已经为新旧 apk 提取了 CERT.RSA。他们都使用相同的密钥库和密钥,但我注意到我使用了错误的发布别名。下面是两个 apk 的指纹,顶部是旧的,底部是新的。

C:\OpenSSL-Win64\bin>keytool -printcert -file CERT.RSA
Owner: CN=matthew womersley, OU=dev, O=carefreegroup, L=wakefield, ST=west yorkshire
Issuer: CN=matthew womersley, OU=dev, O=carefreegroup, L=wakefield, ST=west yorkshire
Serial number: 6144ad2c
Valid from: Fri Jan 11 08:55:29 GMT 2013 until: Thu May 14 09:55:29 BST 3012
Certificate fingerprints:
         MD5:  50:63:5E:54:9D:D3:C4:71:A9:4E:3C:F4:27:9E:50:CA
         SHA1: 7C:2C:DB:7E:92:D2:01:46:43:8D:D2:B9:A4:D2:B0:F4:85:E7:16:D9
         SHA256: 38:64:89:4D:A2:37:72:AA:CE:90:5E:34:46:B9:D0:A4:CA:18:B7:07:7A:E2:DB:1D:7C:60:CD:70:F6:77:C5:FF
         Signature algorithm name: SHA256withRSA
         Version: 3

Extensions:

#1: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 3F 95 E8 FA 36 5B 26 07   33 72 8B 09 37 0C 18 C5  ?...6[&.3r..7...
0010: 3B 5A 19 42                                        ;Z.B
]
]


C:\OpenSSL-Win64\bin>keytool -list -keystore .keystore
keytool error: java.lang.Exception: Keystore file does not exist: .keystore

C:\OpenSSL-Win64\bin>keytool -printcert -file CERT.RSA
Owner: CN=matthew womersley, OU=dev, O=carefreegroup, L=wakefield, ST=west yorkshire
Issuer: CN=matthew womersley, OU=dev, O=carefreegroup, L=wakefield, ST=west yorkshire
Serial number: 6144ad2c
Valid from: Fri Jan 11 08:55:29 GMT 2013 until: Thu May 14 09:55:29 BST 3012
Certificate fingerprints:
         MD5:  50:63:5E:54:9D:D3:C4:71:A9:4E:3C:F4:27:9E:50:CA
         SHA1: 7C:2C:DB:7E:92:D2:01:46:43:8D:D2:B9:A4:D2:B0:F4:85:E7:16:D9
         SHA256: 38:64:89:4D:A2:37:72:AA:CE:90:5E:34:46:B9:D0:A4:CA:18:B7:07:7A:E2:DB:1D:7C:60:CD:70:F6:77:C5:FF
         Signature algorithm name: SHA256withRSA
         Version: 3

我在单击“生成签名的 Apk”时指定了正确的发布别名,但仍然存在错误,尽管有所不同。

该包与同名的现有包冲突

。 我尝试使用以下链接手动构建新的 apk:

link

C:\Users\mattheww\StudioProjects\nfcscanner3>gradlew assembleRelease
Downloading https://services.gradle.org/distributions/gradle-2.14.1-all.zip


Unzipping C:\Users\mattheww\.gradle\wrapper\dists\gradle-2.14.1-all\8bnwg5hd3w55iofp58khbp6yv\gradle-2.14.1-all.zip to C:\Users\mattheww\.gradle\wrapper\dists\gradle-2.14.1-all\8bnwg5hd3w55iofp58khbp6yv

FAILURE: Build failed with an exception.

* Where:
Build file 'C:\Users\mattheww\StudioProjects\nfcscanner3\app\build.gradle' line: 1

* What went wrong:
A problem occurred evaluating project ':app'.
> java.lang.UnsupportedClassVersionError: com/android/build/gradle/AppPlugin : Unsupported major.minor version 52.0

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

BUILD FAILED

Total time: 29.982 secs

.

如果两个应用程序的密钥库和指纹匹配,谁能解释为什么新应用程序仍然无法升级?

[更新 2]

我刚刚记得,当我将 Eclipse 项目导入 Android Studio 时,它不会正确构建。应用程序对象存在问题。我的 Appication 对象称为 NfcScannerApplication,我有一个以相同名称实现的类(清单中也有描述)。

一旦导入 Android Studio,构建并推送到设备上,Android 表示找不到 Application 类。所以我用下面的代码似乎解决了这个问题。

public static NfcScannerApplication getRealApplication (Context applicationContext)
    {
        Log.e(TAG, "inside NfcScannerApplication getRealApplication");
        NfcScannerApplication application = null;

        if (applicationContext instanceof NfcScannerApplication)
        {
            application = (NfcScannerApplication) applicationContext;
        }
        else
        {
            Application realApplication = null;
            Field magicField = null;
            try
            {
                magicField = applicationContext.getClass().getDeclaredField("realApplication");
                magicField.setAccessible(true);
                realApplication = (Application) magicField.get(applicationContext);
            }
            catch (NoSuchFieldException e)
            {
                Log.e(TAG, e.getMessage());
            }
            catch (IllegalAccessException e)
            {
                Log.e(TAG, e.getMessage());
            }

            application = (NfcScannerApplication) realApplication;
        }

        return application;
    }



    // the above method is commented out and this is used
    //because the migration process from Eclipse to Android
    //needed it. see below
    //https://stackoverflow.com/questions/36495954/bootstrapapplication-cannot-be-cast-to-applicationclass

它使用反射来获取 Application 类。这可能是为什么即使我使用相同的密钥库等,Android 认为设备上存在具有相同名称的不同应用程序的原因吗?

[更新 3] 我似乎找到了问题所在。 :) 我有一个 ContentProvider 在首次加载应用程序时获取应用程序上下文。我调用 getContext 并将其转换为我的 Application 类。

我现在做的是调用 getContext.getApplicationContext() ,它现在工作正常。下面是我现在使用的代码,上面已经注释掉了旧代码。

//old code
//Context context = getContext();
      //nfcAppObj = (NfcScannerApplication) getContext();


//new code
       Context applicationContext = getContext().getApplicationContext();
       nfcAppObj = getRealApplication(applicationContext);

【问题讨论】:

  • 您确定密钥库是正确的吗?如果您确定我认为您的密钥库是如何被篡改的。你可以检查这个链接。 stackoverflow.com/questions/13535424/…
  • @turtleboy 您是在 Android Studio 中以发布模式还是调试模式对构建进行签名?
  • @savepopulation 嗨,我在 5 年前在我的服务器上保存了原始密钥库的副本。今天早些时候,我下载了该密钥库并将 Android Studio 指向它。不幸的是,我仍然收到相同的消息。所以我认为我的本地密钥库副本没有损坏。
  • @AnuragSingh 嗨,我已经在 gradle 中指定了发布的 buildType。在 nAndroid studio 中,点击 Build->Generate Signed Apk。从这里我指定密钥库和密码。这会生成我的 apk
  • @turtleboy 其签名错误,您需要使用 APKSigner V2 对 APK 进行签名,您可以在此链接中找到 stackoverflow.com/questions/42605171/…

标签: android android-studio apk


【解决方案1】:

如果您有旧的 apk,您可以使用它来获取用于签名的证书的详细信息。 (从 apk 中提取 CERT.RSA 文件 - 解压缩 - 然后在该文件上运行 openssl 应用程序。)

unzip -p App.apk META-INF/CERT.RSA |openssl pkcs7 -inform DER -noout -print_certs -text

然后使用 keytool(java 自带的)列出你的密钥库中的证书,看看你是否找到了匹配,或者你认为正确的证书是否真的匹配。

供您参考:

Getting certificate details from an apk

How do I find out which keystore was used to sign an app?

【讨论】:

    【解决方案2】:

    如果 Play 商店拒绝您的 apk,这意味着您的密钥库不是原始密钥,则将您签名的 apk 发布到 play 商店的 beta 或 alpha 部分。

    如果 Play 商店接受了您的 apk,则尝试从 Play 商店更新您安装的 apk。

    如果您的应用未在 Play 商店中列出,您可以从设备中提取您以前的 apk 并比较两个 APK 签名 SHA1

    获取 apk 的 SHA1 How do I find out which keystore was used to sign an app?

    【讨论】:

    • 您好,我们不使用 Play 商店,因为 apk 依赖于服务器应用程序,我们的 300 名客户中的一些可能使用不同版本的服务器应用程序。所以我决定在我们的私人服务器上托管 apk,这样我们就可以控制哪家公司的手机在服务器应用程序升级后升级。
    • 从模拟器中提取 apk 然后检查两个 apk SHA1
    【解决方案3】:

    除非您做一些特别的事情,否则当您在 Android Studio 中单击“播放”按钮时,它会使用一个临时的、特定于 AS 的调试密钥对应用程序进行签名,然后将其安装到您的设备上。

    Eclipse 做了非常相似的事情。

    如果您正在谈论使用 Android Studios“生成签名的 APK”,请尝试以下调试步骤:

    • 手动通过adb安装apk,看看是否依旧报错。
    • 自己通过gradle给apk签名,看看是否依旧报错。

    如果这两个步骤都不起作用,我认为可以相当安全地假设您使用的密钥与以前不同。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-13
      • 1970-01-01
      • 1970-01-01
      • 2015-11-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多