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
}
}