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