【Unity】Androidアプリを復帰時に再起動する

ネコニウム研究所

PCを利用したモノづくりに関連する情報や超個人的なナレッジを掲載するブログ

【Unity】Androidアプリを復帰時に再起動する

2022-5-24 |

Unityで作ったAndroidアプリを復帰時に再起動させたい!

概要

この記事では、Unityで作ったAndroidアプリを復帰時に再起動させる手順を掲載する。

仕様書

環境

  • Unity 2021.3.0f1

手順書

下記のスクリプトをシーンで読み込まれるゲームオブジェクトにアタッチする。

using UnityEngine;

public class RestartController : MonoBehaviour
    {
    private bool _isFirst = true;

    private void OnApplicationPause(bool pauseStatus)
    {
        if (pauseStatus)
        {
        }
        else
        {
            if (_isFirst)
            {
                _isFirst = false;
            }
            else
            {
                RestartAndroid();
            }
        }
    }

    private static void RestartAndroid()
    {
        if (Application.isEditor) {
            return;
        }

        using (var unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
        {
            const int kIntent_FLAG_ACTIVITY_CLEAR_TASK = 0x00008000;
            const int kIntent_FLAG_ACTIVITY_NEW_TASK = 0x10000000;

            var currentActivity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
            var pm = currentActivity.Call<AndroidJavaObject>("getPackageManager");
            var intent = pm.Call<AndroidJavaObject>("getLaunchIntentForPackage", Application.identifier);

            intent.Call<AndroidJavaObject>("setFlags", kIntent_FLAG_ACTIVITY_NEW_TASK | kIntent_FLAG_ACTIVITY_CLEAR_TASK);
                currentActivity.Call("startActivity", intent);
                currentActivity.Call("finish");
                var process = new AndroidJavaClass("android.os.Process");
                int pid = process.CallStatic<int>("myPid");
                process.CallStatic("killProcess", pid);
        }
    }
}

OnApplicationPauseメンバー関数でアプリの復帰を検出するんだけども、シーンが最初に起動するタイミングでも復帰時と同様にpauseStatus引数がfalseの状態で呼び出される。

なので、メンバー変数bool _isFirstでシーンの起動時かどうかを判定してる。

注意点

PlayerPrefsを使ってデータを保存するフレームとRestartAndroid関数を呼び出すフレームをずらさないとPlayerPrefs.Saveなどの関数が反映されないので注意。

これでハマりかけちゃって、たまに反映されることもあるもんだから困っちゃう。
無理やりアプリを再起動させてる感じなんで、その弊害なんだと思う。

PlayerPrefs.Saveなどの関数の実行時にフラグを立てて、その後、Update関数内で適当に1秒程度フレーム計測後にRestartAndroid関数を呼び出してアプリを再起動すれば、PlayerPrefsの操作はちゃんと反映された。

まだ試せてませんが、ファイルの出力関連も同じことになるんじゃないかと思う。

まとめ(感想文)

Androidアプリって長時間放置したあとに復帰しようとするといろいろ(特に通信関係)不具合が出ることが多いので、思い切って再起動すると楽かもね!

引用・参考文献

下記のoverstackflowの記事が参考になりました。ありがとうございました。