Unity IAP v1.9.2 を使うと、Android で ActivityNotFoundException が起きることがある件について

  • 6
    いいね
  • 0
    コメント

はじめに

この記事は Unity Advent Calendar 2016 の9日目の記事になります。

通称 (?) ビルドおじさん として Unibook を執筆させていただいたり、勉強会で発表させていただいたりしている関係から、「今年はビルドネタを書こう!」と思っておりました。
そんな矢先に 本業 のほうで開発しているプロダクトで表題の問題が発生したため、渡りに船ってコトで本記事を執筆するに至っております。

結論

出力された Android Project の AndroidManifest.xmlapplication ノードの下に以下のノードを追加しましょう。

<activity
        android:name="com.unity.purchasing.googleplay.PurchaseActivity"
        android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen"
        android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen" />

manifest > application > activity ってな関係になっていれば OK!
元々ある activity ノードの直下にでも書けば良いんじゃないかな?

環境

  • OS: OS X El Capitan 10.11.6
  • Unity: 5.3.6p6
    • Unity IAP v1.9.2
  • gradle: 2.10
  • Java: 1.8.0_66

前提

  • Unity からの出力は APK ビルドではなく、 Export Project にて実行
  • PostProcessBuild にて build.gradle ファイルを出力先に配置しつつ、 gradle コマンドをキック

現象

AndroidManifest.xml に手を入れずに gradle コマンドでビルドしてあげると、ビルド自体は成功する。
が、実際に課金処理を実行しようとすると以下のような Exception を吐いて課金処理が実行されない。

I/Unity: AndroidJavaException: android.content.ActivityNotFoundException: Unable to find explicit activity class {$ProjectPackageName$/com.unity.purchasing.googleplay.PurchaseActivity}; have you declared this activity in your AndroidManifest.xml?

$ProjectPackageName$ んトコは、実際のプロダクトのパッケージ名が入る。

実際に aapt コマンドでビルドされた APK をチェックしてみても、そのような Activity は定義されていない。

$ aapt dump xmltree path/to/APK.apk AndroidManifest.xml

原因

gradle を使ってビルドする際に、 AndroidManifest.xml のマージが巧いこと行われなくなってしまったコトが原因っぽい。
もう少し詳しく書くと、出力先のディレクトリにプロジェクト本体とは別に Unity IAP によって生成される GoogleAIDL, GooglePlay, common とかのディレクトリが出力されているが、その中にある AndroidManifest.xml がマージされていない。
元々は .aar ファイルが配置されてた、とかだったのかな…?覚えてないけど。
少なくとも Unity IAP v1.9.0 の時点では、ヨシナにマージされていた模様。

対処

本当は、 build.gradle とかを修正するコトで対応したかったが、どうやっても GooglePlay とかのディレクトリをプロジェクトとして認識させることが出来なかった。
仕方が無いので、 GooglePlay/libs/ 以下の jar ファイルを dependencies に追加して、 AndroidManifest.xml を手修正するコトにした。
(もっと gradle について勉強しないとダメだな…。)

build.gradle は以下のような感じになった。

build.gradle
// (前略)

allprojects {
    repositories {
        mavenCentral()
        maven { url 'file://' + new File(System.getProperty('user.home'), '.m2/repository').absolutePath }
        flatDir {
            dirs '__APP_NAME__/libs'
        }
    }
}

apply plugin: 'com.android.application'

android {
    // (中略)

    dependencies {
        compile fileTree(dir: '__APP_NAME__/libs', include: '*.jar')

        // unity の classes.jar は Maven のローカルリポジトリに突っ込んでおく
        compile 'com.unity3d:unity3d:__UNITY_VERSION__'

        // この辺は mavenCentral にある…んだと思う
        compile 'com.android.support:support-v4:23.0.+'
        compile 'com.google.android.gms:play-services:6.5.87'

        // ↓がポイント
        compile fileTree(dir: 'common/libs', include: '*.jar')
        compile fileTree(dir: 'GoogleAIDL/libs', include: '*.jar')
        compile fileTree(dir: 'GooglePlay/libs', include: '*.jar')
    }

    // .aar ファイルが配置されなくなったので意味無いけど、一応書いておく
    fileTree(dir: '__APP_NAME__/libs', include: '**/*.aar').each { File file ->
        dependencies.add("compile", [name: file.name.lastIndexOf('.').with { it != -1 ? file.name[0..<it] : file.name }, ext: 'aar'])
    }
}

おわりに

そんなわけで、直近でドハマりした事象をまとめてみました。
「こんな方法で AndroidManifest.xml マージできるよ!」とか「この build.gradle を書いたのは誰だぁっ!」とか「 monry さんの会社 に興味あるんで、遊びに行きたい!」とかあれば、コメ欄なり Twitter なり Facebook なりでドシドシどうぞ!

明日の Unity Advent Calendar 2016 は、 @lycoris102 さんの「GO MAPの世界におもむろに雨とか雪とか降らす」です!