LOADING

加载过慢请开启缓存 浏览器默认开启

Android ホームボタンの検知について

Homeキーはシステムのボタンであり、onKeyDown では検知することができません。
そのため、Homeキーのイベントを検知するには、ちょっとだけトリックを使う必要があります。
それは、 Intent.ACTION_CLOSE_SYSTEM_DIALOGSBroadcastReceiver です。


Intent.ACTION_CLOSE_SYSTEM_DIALOGS

このブロードキャストは、システムダイアログ(たとえば電源メニュー、Homeキーの押し、通知パネルのスワイプダウンなど)がシステムによって閉じられる際に送信されます。主に以下の用途で使用されます:

  • Homeキーの短押し を検知する
  • システムがダイアログを閉じようとしている(例:電源ボタンの長押し)状況を検知する
  • 一部のTVシステムにおいて、リモコンに関連するメニューのクローズイベントを検知する

まず、BroadcastReceiver を継承したクラスを作成して、Intent.ACTION_CLOSE_SYSTEM_DIALOGSを受信するようにします:

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.util.Log
import com.unity3d.player.UnityPlayer

class SystemDialogsBroadcastReceiver : BroadcastReceiver() {  
    override fun onReceive(context: Context, intent: Intent) {  
        if (intent.action == Intent.ACTION_CLOSE_SYSTEM_DIALOGS) {  
            val reason = intent.getStringExtra("reason")  
            when (reason) {  
                "homekey" -> { // Home button press
                    UnityPlayer.UnitySendMessage("SceneManager", "OnAndroidKeyDown", "home")
                }  
                "recentapps" -> { // Home button hold
                    Log.d("SystemBroadcastReceiver", "Recent apps button pressed")  
                }  
            }  
        }  
    }  
}

次に、MainActivity でこのブロードキャストレシーバーを登録します:

class MainActivity : UnityPlayerActivity() {
    private lateinit var broadcastReceiver: SystemDialogsBroadcastReceiver

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        
        broadcastReceiver = SystemDialogsBroadcastReceiver()
    }

    override fun onResume() {  
        super.onResume()  
        
        val filter = IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)  
        registerReceiver(broadcastReceiver, filter)  
    }  
  
    override fun onPause() {  
        super.onPause()  
        
        unregisterReceiver(broadcastReceiver)  
    }
}

このように、Unity の SceneManager オブジェクトの OnAndroidKeyDown メソッドが呼び出され、home というパラメータが渡されます。

Unity 側の受信

BroadcastReceiver のコードで Unity の SceneManager オブジェクトの OnAndroidKeyDown メソッドを呼び出していますから、Unity 側でこのメソッドを実装します:

// Created by LunarEclipse on 2024-7-14 10:6.

using System;
using UnityEngine;

namespace USEN.Games.Common
{
    public class RemoteControlHandler : MonoBehaviour
    {
        public void OnAndroidKeyDown(string keyName) 
        {
            Debug.Log($"[UsenRemoteControlHandler] Key pressed: {keyName}");
            UsenEvents.OnRemoconButtonClicked.Invoke(this, keyName);
            
            switch (keyName)
            {
                case "home":
                    UsenEvents.OnRemoconHomeButtonClicked.Invoke(this, EventArgs.Empty);
                    break;
            }
        }
    }
}

Homeキーを押すとき、イベント OnRemoconHomeButtonClicked を送信する。
そして、イベントをサブスクライブして、ホームボタンが押されたときのイベントを受信します。

namespace USEN.Games.Roulette
{
    public class RouletteStartView : Widget
    {
        private async void Start()
        {
            UsenEvents.OnRemoconHomeButtonClicked += OnRemoconHomeButtonClicked;
        }
        
        private void OnRemoconHomeButtonClicked(object sender, EventArgs e)  
        {  
            Application.Quit();  
        }
    }
}

これで、Homeキーを押すと、Unity 側の OnAndroidKeyDown メソッドが呼び出され、プログラムを終了することができます。