using System; using System.IO; using UnityEngine; /// /// Android power control entry point. /// Real device shutdown requires firmware support, system signature, or a vendor broadcast receiver. /// public static class AndroidPowerController { private const string DefaultShutdownBroadcastAction = "com.dcx.ruiyiweiux.ACTION_SHUTDOWN"; private const string RequestShutdownAction = "android.intent.action.ACTION_REQUEST_SHUTDOWN"; private const string InternalRequestShutdownAction = "com.android.internal.intent.action.REQUEST_SHUTDOWN"; private const string KeyConfirmExtra = "android.intent.extra.KEY_CONFIRM"; public static bool TryShutdownDevice() { #if UNITY_ANDROID && !UNITY_EDITOR bool broadcastSent = SendShutdownBroadcast(GetShutdownBroadcastAction()); bool requestStarted = StartAndroidShutdownRequest(RequestShutdownAction); bool internalRequestStarted = StartAndroidShutdownRequest(InternalRequestShutdownAction); bool shellCommandStarted = TryExecuteShutdownCommand(); if (!broadcastSent && !requestStarted && !internalRequestStarted && !shellCommandStarted) { Debug.LogWarning("AndroidPowerController: 关机请求未发送成功,将回退为退出应用"); return false; } Debug.Log($"AndroidPowerController: 关机请求结果 broadcast={broadcastSent}, request={requestStarted}, internalRequest={internalRequestStarted}, shell={shellCommandStarted}"); return requestStarted || internalRequestStarted || shellCommandStarted; #else return false; #endif } private static bool SendShutdownBroadcast(string action) { #if UNITY_ANDROID && !UNITY_EDITOR try { using (var unityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer")) using (var activity = unityClass.GetStatic("currentActivity")) using (var intent = new AndroidJavaObject("android.content.Intent", action)) { intent.Call("putExtra", "reason", "user_exit"); intent.Call("putExtra", "confirm", false); activity.Call("sendBroadcast", intent); Debug.Log($"AndroidPowerController: 已发送关机广播 {action}"); return true; } } catch (Exception ex) { Debug.LogWarning($"AndroidPowerController: 发送关机广播失败: {ex.Message}"); return false; } #else return false; #endif } private static string GetShutdownBroadcastAction() { #if UNITY_ANDROID && !UNITY_EDITOR try { string configuredAction = ReadShutdownBroadcastAction(Path.Combine(Application.persistentDataPath, "config_android.ini")); if (!string.IsNullOrEmpty(configuredAction)) { return configuredAction; } configuredAction = ReadShutdownBroadcastAction(Path.Combine(Application.streamingAssetsPath, "config_android.ini")); if (!string.IsNullOrEmpty(configuredAction)) { return configuredAction; } } catch (Exception ex) { Debug.LogWarning($"AndroidPowerController: 读取关机广播配置失败: {ex.Message}"); } #endif return DefaultShutdownBroadcastAction; } private static string ReadShutdownBroadcastAction(string configPath) { if (string.IsNullOrEmpty(configPath) || !File.Exists(configPath)) { return null; } foreach (var line in File.ReadAllLines(configPath)) { if (line.StartsWith("shutdownBroadcastAction=", StringComparison.OrdinalIgnoreCase)) { return line.Substring("shutdownBroadcastAction=".Length).Trim(); } } return null; } private static bool StartAndroidShutdownRequest(string action) { #if UNITY_ANDROID && !UNITY_EDITOR try { using (var unityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer")) using (var activity = unityClass.GetStatic("currentActivity")) using (var intent = new AndroidJavaObject("android.content.Intent", action)) { intent.Call("putExtra", KeyConfirmExtra, false); intent.Call("putExtra", "android.intent.extra.USER_REQUESTED_SHUTDOWN", true); intent.Call("addFlags", 0x10000000); // FLAG_ACTIVITY_NEW_TASK activity.Call("startActivity", intent); Debug.Log($"AndroidPowerController: 已发起系统关机请求 {action}"); return true; } } catch (Exception ex) { Debug.LogWarning($"AndroidPowerController: 系统关机请求失败 {action}: {ex.Message}"); return false; } #else return false; #endif } private static bool TryExecuteShutdownCommand() { #if UNITY_ANDROID && !UNITY_EDITOR return TryExecuteShellCommand("su -c reboot -p") || TryExecuteShellCommand("reboot -p") || TryExecuteShellCommand("svc power shutdown"); #else return false; #endif } private static bool TryExecuteShellCommand(string command) { #if UNITY_ANDROID && !UNITY_EDITOR try { using (var runtime = new AndroidJavaClass("java.lang.Runtime")) using (var currentRuntime = runtime.CallStatic("getRuntime")) { currentRuntime.Call("exec", command); Debug.Log($"AndroidPowerController: 已执行关机命令 {command}"); return true; } } catch (Exception ex) { Debug.LogWarning($"AndroidPowerController: 执行关机命令失败 {command}: {ex.Message}"); return false; } #else return false; #endif } }