【Android】apkでの「アプリはインストールされていません。」というエラーは証明書が違うせいかもしれない

とあるシステム開発において、スマホ(Android)アプリを作成しました。
発注企業内でのみ使用するアプリであることから、ストアに申請して配信ということはせず、スマホアプリの更新はapkファイルを用いて行うことになりました。
ところがアップデート用のapkファイルを実行しても「アプリはインストールされていません」というエラーが表示され、アプリが更新されない事象が発生していました。
検索して出てくる内容も根本的な対策ではなく、アンインストール後に入れなおすことでしか対処できず難航……。
今回はその原因調査および対処を行った話です。

結論

根本的な原因は、既にスマホにインストールされているアプリの署名と、アップデートに使用するapkの署名が異なっていたことでした。

直接的な原因は、デバッグビルドを行った(apkファイルを作成した)PCが異なったことでした。

現象の説明

状況の再現として、空のプロジェクト(testupdate)を使用します。
あらかじめアプリをスマホにインストールしておきます。
また、設定から提供元不明アプリを許可しておきます(許可方法は割愛)。

まずはアップデート可能なapkファイルを用いてアップデートを試みます。
apkファイルを実行すると、以下のようなダイアログが表示されます。

インストールを選択すると、インストール処理が実行され、無事完了すると以下のようなダイアログが表示されます。

次にアップデートに失敗するapkファイルを用いてアップデートを試みます。
apkファイルを実行して、インストールを選択すると同様にインストール処理が実行されるのですが、最後に以下のようなダイアログが表示されます。
「アプリはインストールされていません。」というものです。

インストールに失敗し、アプリはアップデートできていません。
こういう現象が発生していました。

  1. 実機を繋いでビルドを行い、あらかじめスマホにアプリをインストールしておきます。
  2. Build > Build Bundle(s) / APK(s) > Build APK(s)を選択し、デバッグビルドを行ってapkファイルを作成します。⇒ アップデート可能なapkファイル
  3. C:\Users\user\.android\debug.keystore ファイルを削除します。
  4. Build > Build Bundle(s) / APK(s) > Build APK(s)を選択し、デバッグビルドを行ってapkファイルを作成します。 ⇒ アップデート不可能なapkファイル

調査

スマホ上に表示される内容は前項で確認した通り。
インストールに失敗したことしか分からず、なぜインストールに失敗したのかは分かりません。

またLogcatを一通り見て見たのですが、それらしいエラーも存在せず……。

お手上げ状態だったのですが、adbを使用することでとあるエラーを確認できました。
adbを使用して、強制的にapkファイルのインストールを試みた時の話です。

adbを使用して強制的にインストールするコマンドは以下。

-r オプションは、既存アプリのデータを保持したまま、再インストールを行うものです。

アップデートに成功するapkファイルを使用した場合はSuccessとなり、無事アップデート(インストール)ができます。

ところがアップデートに失敗していたapkファイルを使用した場合は、以下のように表示されたのです。

Failure [INSTALL_FAILED_UPDATE_INCOMPATIBLE: Package com.example.testupdate.test signatures do not match previously installed version; ignoring!]

signatures(署名)が前にインストールされたバージョンのものと一致していないとのこと!
解決の糸口が見えてきました。

対処

署名が異なるという点に着目して更に調査した結果、今回の原因はデバッグビルドを異なるPCで実施し、apkファイルを作成していたためだということが判明しました。

デバッグビルドの署名に使用している証明書は、C:\Users\user\.android\debug.keystoreです(Windows Vista, 7, 8, 10, 11の場合)。
このファイルを異なるPC間で共通使用してデバッグビルドをすることで、apkファイルを用いたアップデートに無事成功しました!

なお補足ですが、そもそも配布するためのapkファイルは、デバッグビルドで作成するのではなく、リリース用の証明書を準備して、リリースで作成するようにすることを推奨しておきます。
そこんとこ良くなかったよね……というのは今回の反省でした。

結論:再び

スマホでapkファイルを実行してインストールする時に、「アプリはインストールされていません。」というエラーが表示される理由として、既にインストールされているアプリの署名と、apkファイルの署名が異なっている場合がある。

同じアプリのapkファイルを作成する場合は、デバッグビルドならdebug.keystoreファイルを、リリースなら共通の署名ファイルを使用すること。

参考

Androidアプリをダウングレードする方法! apkファイルをダウンロードして元の旧バージョンへ戻そう
この記事では、Androidアプリのバージョンダウン手順をまとめています。apkファイルを用意できればダウングレードは簡単です。もしアプリデータを保持したい場合、adb環境またはroot環境が必要です。
アプリへの署名  |  Android Studio  |  Android Developers
アプリ署名とセキュリティに関する重要な概念、Google Play でリリースするアプリに Android Studio で署名する方法、Play アプリ署名にオプトインする方法について説明します。

コメント

タイトルとURLをコピーしました