[Unity] Google Play Billing Library バージョン 5 へのアップデート

先日Google Play Consoleに以下のような Google Play Billing Library の更新案内が来ていました。

Play Billing Library のバージョンのサポート終了

このアプリで古いバージョンの Google Play 請求サービスが使用されていることが検出されました。2023年11月1日より、すべてのアプリ アップデートで Google Play Billing Library バージョン 5 以降を使用する必要があります。

ご対応のお願い: 一般公開されている APK が Google Play Billing Library の最新バージョンに更新されていることをご確認ください。製品版で公開されるすべての APK や App Bundle が対象となります。

Unity IAPのPlay Billing Libraryバージョンアップでハマってしまったのでまとめておきます。




Google Play Billing Library アップデート手順

 Unityではアプリ内購入ライブラリでIAPを提供しています。アップデート手順は簡単で、Unity EditorからWindows→Package Manager→In App PurchasingでPlay Billing Library v5に対応した4.8.0以上のバージョンを選択すればあとはよろしくやってくれます。

一点、PurchaseManagerのIStoreListenerのインタフェースが増えているので、以下のメソッドを追加しておきます。

public void OnInitializeFailed(InitializationFailureReason error, string? message)

互換性にも問題なく、購入処理などもなんの問題もなく行えました。

ハマった話

ここまではIAPのアップデートを何も問題なく行う方法を説明しました。ここからは私が間違ったアップデート方法を行い、ハマった話です。

Google Play Plugins for Unity のアップデート

IAPがPlay Billing Library v5に未対応だった時、Play Billing Library v5のアップデートを以下のサイトを参考に試みました。

この手順にある「Google Play Plugins for Unity の最新リリースを、GitHub のリポジトリ リリースページからダウンロードします。」のところで、書いてある通りにプラグインをダウンロードしてアップデートしました。これにより、com.google.play.coreやcom.google.play.commonといったパッケージが最新版にアップデートされることになります。

ビルドして内部テストへリリース

ビルドは正常に通ったので、動作確認もすることなく、早速Play Consoleの内部テストへリリースしました。小一時間すると、リリース前レポートが上がってきます。いくつかのバージョンで起動の確認をしてくれて、その結果を確認できるようなサービスですかね。

そこで以下のようなエラーを指摘されました。

Exception Process: com.hirokuma.sorobanall, PID: 18356
java.lang.IllegalArgumentException: com.hirokuma.sorobanall: Targeting S+ (version 31 and above) requires that one of FLAG_IMMUTABLE or FLAG_MUTABLE be specified when creating a PendingIntent.
Strongly consider using FLAG_IMMUTABLE, only use FLAG_MUTABLE if some functionality depends on the PendingIntent being mutable, e.g. if it needs to be used with inline replies or bubbles.
  at android.app.PendingIntent.checkFlags (PendingIntent.java:401)
  at android.app.PendingIntent.getBroadcastAsUser (PendingIntent.java:671)
  at android.app.PendingIntent.getBroadcast (PendingIntent.java:658)
  at androidx.work.impl.utils.ForceStopRunnable.getPendingIntent (ForceStopRunnable.java:174)
  at androidx.work.impl.utils.ForceStopRunnable.isForceStopped (ForceStopRunnable.java:108)
  at androidx.work.impl.utils.ForceStopRunnable.run (ForceStopRunnable.java:86)
  at androidx.work.impl.utils.SerialExecutor$Task.run (SerialExecutor.java:75)
  at java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1137)
  at java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:637)
  at java.lang.Thread.run (Thread.java:1012)

Android12,13で正しく起動できていませんでした。調べると、build.gradleに以下の一文を追加することで対応回避できるようでしたので、早速追加しました。

implementation 'androidx.work:work-runtime-ktx:2.7.0-alpha03'

ビルドも問題なくパスし、2回目の内部テストリリースへ向かいます。

またも起動失敗・・・

前のエラーを修正して、再度内部テストリリースしたのですが、今度はまた別のエラーに出くわしました。

backtrace:
  #00  pc 0x00000000000531f4  /apex/com.android.runtime/lib64/bionic/libc.so (abort+164)
  #01  pc 0x00000000006d2a4c  /apex/com.android.art/lib64/libart.so (art::Runtime::Abort(char const*)+704)
  #02  pc 0x0000000000016ea8  /apex/com.android.art/lib64/libbase.so
  #03  pc 0x0000000000016450  /apex/com.android.art/lib64/libbase.so (android::base::LogMessage::~LogMessage()+352)
  #04  pc 0x000000000038418c  /apex/com.android.art/lib64/libart.so (art::Thread::AssertNoPendingExceptionForNewException(char const*) const+548)
  #05  pc 0x0000000000381f88  /apex/com.android.art/lib64/libart.so (art::ThrowException(char const*, art::ObjPtr<art::mirror::Class>, char const*, std::__va_list*) (.__uniq.13088424560882570482564097729983985904.llvm.17521490227315207684)+500)
  #06  pc 0x0000000000496e08  /apex/com.android.art/lib64/libart.so (art::ThrowNoSuchMethodError(art::InvokeType, art::ObjPtr<art::mirror::Class>, std::__1::basic_string_view<char, std::__1::char_traits<char> >, art::Signature const&)+288)
  #07  pc 0x0000000000490154  /apex/com.android.art/lib64/libart.so (NterpGetMethod+11152)
  #08  pc 0x000000000020f540  /apex/com.android.art/lib64/libart.so (nterp_get_method+48)
  #09  pc 0x00000000002041f4  /apex/com.android.art/lib64/libart.so (nterp_op_invoke_interface+116)
  #10  pc 0x000000000020a254  /apex/com.android.art/lib64/libart.so (nterp_helper+3924)
  #11  pc 0x0000000000436b6c  /apex/com.android.art/lib64/libart.so (art_quick_invoke_stub+556)
  #12  pc 0x00000000004cbfc4  /apex/com.android.art/lib64/libart.so (art::JValue art::InvokeVirtualOrInterfaceWithVarArgs<art::ArtMethod*>(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, art::ArtMethod*, std::__va_list)+828)
  #13  pc 0x00000000005ddcf0  /apex/com.android.art/lib64/libart.so (art::JNI<false>::CallVoidMethodV(_JNIEnv*, _jobject*, _jmethodID*, std::__va_list)+184)
  #14  pc 0x000000000032ca28  /data/app/~~DNc9_kifokfwIkFGLqxafg==/com.hirokuma.sorobanall-K6JiCgimrhW5ube5XXeLUA==/lib/arm64/libunity.so (_JNIEnv::CallVoidMethod(_jobject*, _jmethodID*, ...))
  #15  pc 0x000000000033f4bc  /data/app/~~DNc9_kifokfwIkFGLqxafg==/com.hirokuma.sorobanall-K6JiCgimrhW5ube5XXeLUA==/lib/arm64/libunity.so (void JavaMethod<void>::operator()<_jstring*, _jobject*>(_jstring*, _jobject*))
  #16  pc 0x000000000033f23c  /data/app/~~DNc9_kifokfwIkFGLqxafg==/com.hirokuma.sorobanall-K6JiCgimrhW5ube5XXeLUA==/lib/arm64/libunity.so (AndroidAssetPacks::AssetPackManager::Init(bool (*)(char const*)))
  #17  pc 0x0000000000341484  /data/app/~~DNc9_kifokfwIkFGLqxafg==/com.hirokuma.sorobanall-K6JiCgimrhW5ube5XXeLUA==/lib/arm64/libunity.so (UnityInitApplication())
  #18  pc 0x00000000003427f4  /data/app/~~DNc9_kifokfwIkFGLqxafg==/com.hirokuma.sorobanall-K6JiCgimrhW5ube5XXeLUA==/lib/arm64/libunity.so (UnityPlayerLoop())
  #19  pc 0x0000000000357eb8  /data/app/~~DNc9_kifokfwIkFGLqxafg==/com.hirokuma.sorobanall-K6JiCgimrhW5ube5XXeLUA==/lib/arm64/libunity.so (nativeRender(_JNIEnv*, _jobject*))
  #20  pc 0x0000000000440554  /apex/com.android.art/lib64/libart.so (art_quick_generic_jni_trampoline+148)
  #21  pc 0x000000000020a2b0  /apex/com.android.art/lib64/libart.so (nterp_helper+4016)
  #22  pc 0x0000000000209334  /apex/com.android.art/lib64/libart.so (nterp_helper+52)
  #23  pc 0x000000000050a854  /system/framework/arm64/boot-framework.oat

いやぁ、この手の起動でコケるのはガチでしんどいですね。Android12以上の端末を持ち合わせていないので、このバックトレース情報だけで調査して、解決策を探していきました。

原因判明

Unityのバージョンが古い(自分の環境は2020.3.21f1)かつPlay Asset Deliveryが1.7.0より新しいとCrashするようです。

プラグインを最新にしてしまったがために、この辺もアップデートされUnityの古いバージョンも兼ね合って問題を踏んでしまっていたようです。

ちなみに手動で、私が使っていた以下のプラグインを1.7.0に更新すると正しく起動できることが確認できました。

  • com.google.android.appbundle
  • com.google.play.common
  • com.google.play.core
  • com.google.play.review

パッケージはこちらから取得できます。

更新方法はAssets/GooglePlayPlugins以下を全て削除してパッケージのインポートで適用できました。

まとめ

Play Billing Library v5に対応したIAPのリリースを待って取り込めば何の問題もなかったのですが、まさかの先走りでハマってしまいました。

また、ハマって調査中にIAPがリリースされ、適用したけど解決しないというのもハマりが深くなってしまった原因でした。。。

同じようにハマった誰かのヒントになれば幸いです。

コメント