killapp/Assets/Scripts/Utils/AndroidFilePicker.cs
2026-03-30 16:25:00 +08:00

155 lines
4.3 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using UnityEngine;
/// <summary>
/// Android文件选择器 - 调用Android原生文件选择器
/// </summary>
public class AndroidFilePicker : MonoBehaviour
{
public static AndroidFilePicker Instance { get; private set; }
// 回调事件
public event Action<string, string, byte[]> OnFileSelected; // 文件路径, 文件名, 文件数据
public event Action OnFileSelectCanceled;
public event Action<string> 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;
}
}
/// <summary>
/// 打开文件选择器
/// </summary>
/// <param name="mimeTypes">可选的MIME类型过滤器如 "application/octet-stream"</param>
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
}
/// <summary>
/// 从Unity接收文件选择结果
/// </summary>
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);
});
}
/// <summary>
/// 从Unity接收取消事件
/// </summary>
public void OnFileSelectCanceledFromJava()
{
Debug.Log("[FILE-PICKER] [CS] 用户取消选择");
Loom.QueueOnMainThread(() =>
{
OnFileSelectCanceled?.Invoke();
});
}
/// <summary>
/// 从Unity接收错误
/// </summary>
public void OnErrorFromJava(string error)
{
Debug.LogError($"[FILE-PICKER] [CS] 错误: {error}");
Loom.QueueOnMainThread(() =>
{
OnError?.Invoke(error);
});
}
}
/// <summary>
/// 文件选择器回调代理 - 用于Java到C#的回调
/// </summary>
public class FilePickerCallbackProxy : AndroidJavaProxy
{
private AndroidFilePicker _picker;
public FilePickerCallbackProxy(AndroidFilePicker picker) : base("com.unity.filepicker.FilePicker$FilePickerCallback")
{
_picker = picker;
}
/// <summary>
/// 文件选择成功回调
/// </summary>
public void onFileSelected(string filePath, string fileName, byte[] fileData)
{
_picker?.OnFileSelectedFromJava(filePath, fileName, fileData);
}
/// <summary>
/// 用户取消回调
/// </summary>
public void onFileSelectCanceled()
{
_picker?.OnFileSelectCanceledFromJava();
}
/// <summary>
/// 错误回调
/// </summary>
public void onError(string error)
{
_picker?.OnErrorFromJava(error);
}
}