using System; using UnityEngine; /// /// Android文件选择器 - 调用Android原生文件选择器 /// public class AndroidFilePicker : MonoBehaviour { public static AndroidFilePicker Instance { get; private set; } // 回调事件 public event Action OnFileSelected; // 文件路径, 文件名, 文件数据 public event Action OnFileSelectCanceled; public event Action OnError; private AndroidJavaClass _filePickerClass; private void Awake() { if (Instance == null) { Instance = this; DontDestroyOnLoad(gameObject); } else { Destroy(gameObject); } } private void OnDestroy() { if (Instance == this) { Instance = null; } } /// /// 打开文件选择器 /// /// 可选的MIME类型过滤器,如 "application/octet-stream" public void PickFile(string[] mimeTypes = null) { #if UNITY_ANDROID && !UNITY_EDITOR Debug.Log("[FILE-PICKER] [CS] PickFile() 被调用"); try { if (_filePickerClass == null) { Debug.Log("[FILE-PICKER] [CS] 初始化 FilePicker Java类..."); _filePickerClass = new AndroidJavaClass("com.unity.filepicker.FilePicker"); Debug.Log("[FILE-PICKER] [CS] FilePicker Java类初始化成功"); } // 创建回调代理 Debug.Log("[FILE-PICKER] [CS] 创建回调代理..."); FilePickerCallbackProxy callbackProxy = new FilePickerCallbackProxy(this); Debug.Log("[FILE-PICKER] [CS] 回调代理创建成功"); // 调用Java方法 Debug.Log("[FILE-PICKER] [CS] 调用Java方法 pickFile..."); _filePickerClass.CallStatic("pickFile", mimeTypes, callbackProxy); Debug.Log("[FILE-PICKER] [CS] 打开文件选择器成功"); } catch (Exception e) { Debug.LogError($"[FILE-PICKER] [CS] 打开文件选择器失败: {e.Message}\n{e.StackTrace}"); OnError?.Invoke($"打开文件选择器失败: {e.Message}"); } #else Debug.LogWarning("[FILE-PICKER] [CS] 仅在Android平台可用"); OnError?.Invoke("文件选择器仅在Android平台可用"); #endif } /// /// 从Unity接收文件选择结果 /// public void OnFileSelectedFromJava(string filePath, string fileName, byte[] fileData) { Debug.Log($"[FILE-PICKER] [CS] 选择文件成功: {fileName}, 大小: {fileData?.Length ?? 0}"); // 在主线程执行回调 Loom.QueueOnMainThread(() => { OnFileSelected?.Invoke(filePath, fileName, fileData); }); } /// /// 从Unity接收取消事件 /// public void OnFileSelectCanceledFromJava() { Debug.Log("[FILE-PICKER] [CS] 用户取消选择"); Loom.QueueOnMainThread(() => { OnFileSelectCanceled?.Invoke(); }); } /// /// 从Unity接收错误 /// public void OnErrorFromJava(string error) { Debug.LogError($"[FILE-PICKER] [CS] 错误: {error}"); Loom.QueueOnMainThread(() => { OnError?.Invoke(error); }); } } /// /// 文件选择器回调代理 - 用于Java到C#的回调 /// public class FilePickerCallbackProxy : AndroidJavaProxy { private AndroidFilePicker _picker; public FilePickerCallbackProxy(AndroidFilePicker picker) : base("com.unity.filepicker.FilePicker$FilePickerCallback") { _picker = picker; } /// /// 文件选择成功回调 /// public void onFileSelected(string filePath, string fileName, byte[] fileData) { _picker?.OnFileSelectedFromJava(filePath, fileName, fileData); } /// /// 用户取消回调 /// public void onFileSelectCanceled() { _picker?.OnFileSelectCanceledFromJava(); } /// /// 错误回调 /// public void onError(string error) { _picker?.OnErrorFromJava(error); } }