結論から言うと、はい。Google Playはインタプリタで実行される code のライブアップデートを許可しています。 Play Storeの新たな審査なしに、Androidアプリへ新しいJavaScript、HTML、CSSをプッシュできます。ただし、dexやJARなどのネイティブ code をダウンロードすることはできません。 .so ファイル。
この点でGoogleはAppleより明確です。WebView内のJavaScriptに関する例外はポリシーに直接明記されています。本ページではその引用を示し、境界線がどこにあるかを明らかにし、Googleがそれをどう適用しているかを解説します。
これは法的助言ではありません。現在のポリシーの内容と、数千ものアプリが本番環境でどのように運用しているかに基づいています。
Google Playのポリシーの実際の内容
該当するルールは デバイスとネットワークの不正利用に関するポリシーに記載されています:
Google Playを通じて配信されるアプリは、Google Playのアップデートメカニズム以外の方法で、自身を修正、置換、またはアップデートしてはなりません。同様に、アプリはGoogle Play以外のソースから実行可能な code (dex、JAR、.soファイルなど) をダウンロードしてはなりません。この制限は、仮想マシンまたはインタプリタ内で実行され、そのいずれかがAndroid APIへの間接的なアクセスを提供する(WebViewやブラウザ内のJavaScriptなど)code には適用されません。
また、その直後に以下の記載があります:
実行時に解釈言語(JavaScript、Python、Luaなど)をロードするアプリやサードパーティ製の code (SDKなど。例:アプリにパッケージ化されていないもの) は、Google Playポリシーに違反する可能性のある動作を許可してはなりません。
ルールは次の2つです:
- Native code は Google Play からのみ提供されること。 ダウンロードされた dex、JAR、またはネイティブライブラリを含まないこと。
- Interpreted code はどこからでも取得可能ですが、 その動作は常にすべての Play ポリシーに従う必要があります。
Capacitor アプリのウェブレイヤーは、Android WebView 上で動作する JavaScript、HTML、CSS で、Google が挙げているまさにその例です。これは免除対象に含まれます。
線引きはどこにあるか
| live update で許可されるケース | live update でも許可されないケース |
|---|---|
| JavaScript、HTML、CSS のバグ修正 | dex、JAR、APK のダウンロード、または .so ファイル |
| 既存のウェブスタックでのUI変更、文言変更、新規画面の追加 | Google Play のアップデート機構を介さないアプリの置き換え |
| ウェブ code のA/Bテストや段階的ロールアウト | Play ポリシーに違反する code の配信(欺瞞的行為、マルウェア、ポリシー違反コンテンツ) |
| 画像、翻訳、設定の更新 | ストアの説明と異なるアプリに変えること |
| 不具合のあるリリースのロールバック | Android の権限やセキュリティの回避 |
Capgo が配信するのは左側の列だけです。新しい Capacitor プラグインや、新しい権限、 AndroidManifest.xmlGradle の依存関係など、ネイティブに関わる変更は、引き続き Google Play 経由の新しいリリースが必要です。Capgo の バージョンターゲティングは、 新しいネイティブ code を必要とする bundle が古いバイナリに届かないようにします。
Google による取り締まりの仕組み
Google は、ダウンロードされた実行可能な code や、インストール後に挙動が変わる箇所がないかアプリをスキャンします。自動チェックでは、APK の外部から dex やネイティブライブラリをロードしていないかを検知します。WebView 内の JavaScript ではこれらは検知されません。
本当のリスクは2つ目のルールです。live update によってアプリが Play ポリシーで禁止されている動作をする場合、code がどう配信されたかにかかわらず違反となります。「欺瞞的行為」ポリシーは、審査後に機能が変わるアプリにも適用されます。
実務では:
- 公開したアプリの修正や改善には、Live Update を活用してください。
- Play Storeの掲載情報とデータ セーフティ フォームの内容を一致させましょう。
- ネイティブの変更や大規模なリリースはGoogle Play経由で配信し、 段階的なリリース を使えば、徐々に展開できます。
Androidで対応できるスタックは?
AndroidでOTAアップデートを配信できるかどうかは、1つの問いにかかっています。アプリのロジックは実行時に解釈されるか?JavaScriptなどのインタプリタ型 code なら「はい」。ダウンロードしたdex、JAR、ネイティブ .so ファイルは「いいえ」です。FlutterのようなAOTコンパイル型フレームワークは、VMまたはインタプリタ経由でのみ対象となります。
スタック別 Android live update 互換性
| スタック | Androidで code が動く仕組み | ライブアップデートは可能? | ツール |
|---|---|---|---|
| Capacitor | Android WebView内のJavaScript、HTML、CSS | はい | Capgo |
| Ionic (Capacitor 上) | Capacitor と同様 | はい | Capgo |
| Cordova | Android WebView内のJavaScript | はい | Capacitorへの移行後のCapgo、レガシーCordovaプラグイン |
| React Native / Expo | Hermes上のJavaScript bundle | はい、JavaScriptのみ | Expo Updates、セルフホスト型のCodePush代替案 |
| NativeScript | V8上のJavaScript | はい、JavaScriptのみ | 限定的、主に自作 |
| Flutter | ネイティブライブラリへAOTコンパイルされたDart | VMまたはインタプリタ経由のみ | Shorebird |
| ネイティブのKotlin / Java | ART上のdexバイトコード | ネイティブのcodeは不可、WebView内のJavaScriptは可 | リモート構成、Play Feature Delivery |
| Kotlin / Compose Multiplatform | ART上のdexバイトコード | いいえ | リモートコンフィグ、Play Feature Delivery |
| .NET MAUI / Xamarin | APKに同梱された.NETランタイムとネイティブライブラリ | いいえ | リモートコンフィグのみ |
| Unity / Unreal | IL2CPP または C++ でコンパイルされた C# | codeは不可、コンテンツは可 | Asset bundles、Play Asset Delivery、スクリプトコンテンツ(Lua) |
| Web wrapper / TWA | WebViewまたはChromeで読み込まれるWebサイト | 常にライブ状態 | 不要 |
Capacitor、Ionic、Cordova:完全にカバー
UIとビジネスロジックはAndroid WebView上で動作するJavaScriptであり、これはGoogleのポリシーが許可している code の具体例そのものです。live update はWeb bundleを置き換えますが、APK、ネイティブプラグイン、権限は公開時のものが維持されます。
Capgo はWebレイヤーのみを変更するため、設計上コンプライアンスを遵守しています。新しいネイティブプラグインや、AndroidManifest内の AndroidManifest.xml 新しい権限、およびGradleの依存関係の変更には、引き続きGoogle Playでのリリースが必要です。
React NativeとExpo:JavaScriptはOK、ネイティブモジュールはNG
React NativeはHermes上でJavaScript bundleを実行するため、これは解釈型の code とみなされます。Expo Updatesや、現在は廃止されたMicrosoft CodePushがそのbundleを更新します。 CodePushから移行するチームは 代替手段が必要です。ネイティブモジュールやReact Nativeのアップグレードには、新しいリリースが必要になります。
Flutter:VMまたはインタプリタ経由のみ
FlutterはDartを事前にコンパイルして libapp.so新しいものをダウンロードすることは .so 明示的に禁止されているため、標準のFlutterではLive Updateを利用できません。Shorebirdはcodeのプッシュ機能を追加し、Dart仮想マシン経由でアップデートを実行することでPlayのポリシーに準拠しています。詳細は Flutterアプリ向けのLive Update.
ネイティブのKotlin、Java、Kotlin Multiplatformでは、codeのアップデートは不可能です。
ダウンロードしたdexやJARファイルを DexClassLoader 読み込む動作は、まさにポリシーで禁止されている挙動です。Google自身が提供する代替手段は Play Feature Deliveryであり、Google Playを通じてcodeモジュールをダウンロードします。それ以外の場合、ネイティブのcodeを変更することはできません。WebView内でJavaScriptを実行するKotlinやJavaのアプリであれば、そのcodeを更新することは可能です。これは、解釈実行されるcodeがポリシーの例外となっているためです。その他のネイティブロジックは、リモート構成、フィーチャーフラグ、サーバー駆動UI(SDUI)に限定されます。
Unityとゲームエンジン:コンテンツはOK、codeはNG
ゲームのcodeはコンパイルされています。アセットバンドルやPlay Asset Deliveryがコンテンツを管理し、Luaのような組み込みスクリプト言語はcodeとして解釈実行されます。これらは、実行結果がPlayのポリシーに従っている限り、ポリシーで許可されています。
WebラッパーとTrusted Web Activities:本質的にLive Updateが可能
Trusted Web Activity (TWA) や WebView ラッパーがウェブサイトを読み込むため、デプロイのたびに最新の状態に更新されます。Google Play は TWA を受け入れています。オフラインキャッシュやネイティブブリッジの挙動は、そのラッパーの実装に依存します。TWA なら PWA の service worker を利用でき、WebView シェルなら自作の JavaScript ブリッジを公開できます。Capacitor をバンドルしたアプリは、APK 内にウェブバンドルを含め、Live Update 用の一貫したプラグインレイヤーを追加します。
Android でいかなるスタックでも不可能なこと
どのフレームワークでも、live updateにできないこと:
- Google Play 以外から dex, JAR, APK, または native を
.soダウンロードすること - 新しい Android 権限を追加すること
- Google Play のポリシーで禁止されている動作をアプリに行わせること
- Play Store の説明と異なる内容にアプリを変更すること
次のステップ
- iOS の回答: Apple は App Store の審査なしで Live Update を許可しているか?
- コンプライアンス・チェックリスト: Google PlayのOTAコンプライアンス・チェックリスト
- リリース戦略: Google Playコンプライアンス:主要なアップデート戦略
レビュー待ちではなく、今日中に修正をリリース
Capgo Live Updates チャネル、ロールバック、差分アップデート、エンドツーエンド暗号化を備え、JavaScript、HTML、CSSの変更を数分でCapacitorアプリにpushできます。オープンソースでセルフホストも可能です。
bunx @capgo/cli@latest init
最初のアップデートを送信するには、 クイックスタート に従ってください。