【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の記事が参考になりました。ありがとうございました。