407 lines
13 KiB
C#
407 lines
13 KiB
C#
using UnityEngine;
|
||
using System.Collections;
|
||
using System;
|
||
using System.IO;
|
||
using UnityEngine.UI;
|
||
using System.Collections.Generic;
|
||
|
||
|
||
public class CaptureScreenshotMgr : MonoBehaviour
|
||
{
|
||
//public Button StartButton;
|
||
public Button saveButton;
|
||
public Button returnButton;
|
||
public Button shareButton;
|
||
|
||
public Image pictureImage;
|
||
|
||
public GameObject selectPlane;
|
||
|
||
public List<GameObject> buttonGameObject = new List<GameObject>();//用于隐藏按钮
|
||
|
||
public GameObject shuiYin;
|
||
public GameObject header;
|
||
|
||
private void Awake()
|
||
{
|
||
try
|
||
{
|
||
RuntimeLog.Instance?.AddLog("\n=== 初始化 CaptureScreenshotMgr ===");
|
||
|
||
if (header == null)
|
||
{
|
||
header = GameObject.Find("Header");
|
||
RuntimeLog.Instance?.AddLog(header != null
|
||
? "找到 Header 对象"
|
||
: "警告: 未找到 Header 对象");
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
RuntimeLog.Instance?.AddLog($"CaptureScreenshotMgr Awake 错误: {ex.Message}");
|
||
Debug.LogError($"CaptureScreenshotMgr Awake 错误: {ex.Message}");
|
||
}
|
||
}
|
||
public void Start()
|
||
{
|
||
try
|
||
{
|
||
RuntimeLog.Instance?.AddLog("初始化按钮监听器");
|
||
|
||
returnButton.onClick.AddListener(() => {
|
||
RuntimeLog.Instance?.AddLog("点击返回按钮");
|
||
OffSelectPlane();
|
||
});
|
||
|
||
saveButton.onClick.AddListener(() => {
|
||
RuntimeLog.Instance?.AddLog("点击保存按钮");
|
||
StoreScreenshot(tex, _name);
|
||
OffSelectPlane();
|
||
});
|
||
|
||
shareButton.onClick.AddListener(() => {
|
||
RuntimeLog.Instance?.AddLog("点击分享按钮");
|
||
StoreScreenshot(tex, _name);
|
||
ShareFile();
|
||
OffSelectPlane();
|
||
});
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
RuntimeLog.Instance?.AddLog($"按钮初始化失败: {ex.Message}");
|
||
}
|
||
}
|
||
/// <summary>
|
||
/// 保存截屏图片,并且刷新相册(Android和iOS)
|
||
/// </summary>
|
||
/// <param name="name">若空就按照时间命名</param>
|
||
public void CaptureScreenshot(string name = "")
|
||
{
|
||
try
|
||
{
|
||
RuntimeLog.Instance?.AddLog("\n=== 开始截图 ===");
|
||
|
||
// 临时隐藏header
|
||
if (header != null)
|
||
{
|
||
header.SetActive(false);
|
||
}
|
||
|
||
OffbuttonGameObject();
|
||
|
||
_name = string.IsNullOrEmpty(name)
|
||
? $"Screenshot_{GetCurTime()}.png"
|
||
: name;
|
||
|
||
StartCoroutine(CutImage(_name));
|
||
RuntimeLog.Instance?.AddLog($"开始截图: {_name}");
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
RuntimeLog.Instance?.AddLog($"截图失败: {ex.Message}");
|
||
Debug.LogError($"截图失败: {ex.Message}");
|
||
RestoreUIState();
|
||
}
|
||
}
|
||
|
||
// 新增方法:恢复UI状态
|
||
private void RestoreUIState()
|
||
{
|
||
if (header != null)
|
||
{
|
||
header.SetActive(true);
|
||
}
|
||
SetbuttonGameObject();
|
||
}
|
||
|
||
IEnumerator CutImage(string name)
|
||
{
|
||
tex = new Texture2D(Screen.width, Screen.height, TextureFormat.RGB24, true);
|
||
yield return new WaitForEndOfFrame();
|
||
|
||
tex.ReadPixels(new Rect(0, 0, Screen.width, Screen.height), 0, 0, true);
|
||
Sprite sprite = Sprite.Create(tex, new Rect(0, 0, tex.width, tex.height), Vector2.zero);
|
||
pictureImage.sprite = sprite;
|
||
tex.Apply();
|
||
|
||
yield return tex;
|
||
|
||
// 恢复header显示
|
||
if (header != null)
|
||
{
|
||
header.SetActive(true);
|
||
}
|
||
|
||
selectPlane.SetActive(true);
|
||
}
|
||
//截屏并保存
|
||
byte[] byt;
|
||
string path;
|
||
string _name = "";
|
||
|
||
public Texture2D tex;
|
||
|
||
|
||
public Text CeShiText;
|
||
private string lastSavedImagePath; // 新增:保存最后一次截图的路径
|
||
|
||
|
||
// Modify the CutImage coroutine to add the watermark
|
||
// IEnumerator CutImage(string name)
|
||
// {
|
||
// tex = new Texture2D(Screen.width, Screen.height, TextureFormat.RGB24, true);
|
||
// yield return new WaitForEndOfFrame();
|
||
// //tex.ReadPixels(new Rect(0, 0, Screen.width, Screen.height), 0, 0);
|
||
// //GUI.DrawTexture(new Rect(10,10,256,256),tex,ScaleMode.StretchToFill);
|
||
// tex.ReadPixels(new Rect(0, 0, Screen.width, Screen.height), 0, 0, true);
|
||
// Sprite sprite = Sprite.Create(tex, new Rect(0, 0, tex.width, tex.height), Vector2.zero);
|
||
// pictureImage.sprite = sprite;
|
||
// tex.Apply();
|
||
|
||
// yield return tex;
|
||
// selectPlane.SetActive(true);
|
||
|
||
// }
|
||
|
||
|
||
// 存储方法
|
||
void StoreScreenshot(Texture2D tex, string name)
|
||
{
|
||
try
|
||
{
|
||
RuntimeLog.Instance?.AddLog("\n=== 开始保存截图 ===");
|
||
|
||
// 确保DCIM/Camera目录存在
|
||
string dcimPath = "/storage/emulated/0/DCIM/Camera";
|
||
if (!Directory.Exists(dcimPath))
|
||
{
|
||
Directory.CreateDirectory(dcimPath);
|
||
RuntimeLog.Instance?.AddLog($"创建目录: {dcimPath}");
|
||
}
|
||
|
||
// 生成文件名
|
||
string fileName = $"Screenshot_{GetCurTime()}.png";
|
||
string fullPath = Path.Combine(dcimPath, fileName);
|
||
|
||
// 保存图片
|
||
byte[] imageBytes = tex.EncodeToPNG();
|
||
File.WriteAllBytes(fullPath, imageBytes);
|
||
|
||
lastSavedImagePath = fullPath; // 保存路径以供分享使用
|
||
|
||
// 刷新媒体库
|
||
string[] paths = new string[] { dcimPath };
|
||
ScanFile(paths);
|
||
|
||
RuntimeLog.Instance?.AddLog($"截图已保存: {fullPath}");
|
||
|
||
// 关闭预览界面
|
||
OffSelectPlane();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
RuntimeLog.Instance?.AddLog($"保存截图失败: {ex.Message}\n{ex.StackTrace}");
|
||
Debug.LogError($"保存截图失败: {ex.Message}");
|
||
}
|
||
}
|
||
public void deletePicturs()
|
||
{
|
||
File.Delete(path + "/Pictures/Screenshots/" + _name);
|
||
OffSelectPlane();
|
||
}
|
||
public void OpenPlane()
|
||
{
|
||
selectPlane.SetActive(true);
|
||
}
|
||
public void ShareFile()
|
||
{
|
||
try
|
||
{
|
||
RuntimeLog.Instance?.AddLog("\n=== 开始分享截图 ===");
|
||
|
||
if (string.IsNullOrEmpty(lastSavedImagePath))
|
||
{
|
||
RuntimeLog.Instance?.AddLog("错误: 没有可分享的图片");
|
||
return;
|
||
}
|
||
|
||
if (!File.Exists(lastSavedImagePath))
|
||
{
|
||
RuntimeLog.Instance?.AddLog($"错误: 文件不存在: {lastSavedImagePath}");
|
||
return;
|
||
}
|
||
|
||
// 使用 FileProvider 分享文件
|
||
AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
|
||
AndroidJavaObject currentActivity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
|
||
AndroidJavaObject context = currentActivity.Call<AndroidJavaObject>("getApplicationContext");
|
||
|
||
// 创建File对象
|
||
AndroidJavaObject file = new AndroidJavaObject("java.io.File", lastSavedImagePath);
|
||
|
||
// 获取应用包名
|
||
string packageName = context.Call<string>("getPackageName");
|
||
|
||
// 使用FileProvider生成URI
|
||
AndroidJavaClass fileProvider = new AndroidJavaClass("androidx.core.content.FileProvider");
|
||
AndroidJavaObject uri = fileProvider.CallStatic<AndroidJavaObject>(
|
||
"getUriForFile",
|
||
context,
|
||
packageName + ".fileprovider",
|
||
file
|
||
);
|
||
|
||
// 创建分享Intent
|
||
AndroidJavaObject intent = new AndroidJavaObject("android.content.Intent", "android.intent.action.SEND");
|
||
intent.Call<AndroidJavaObject>("setType", "image/*");
|
||
intent.Call<AndroidJavaObject>("putExtra", "android.intent.extra.STREAM", uri);
|
||
intent.Call<AndroidJavaObject>("addFlags", 0x00000001); // FLAG_GRANT_READ_URI_PERMISSION
|
||
|
||
// 创建选择器
|
||
AndroidJavaObject chooser = intent.CallStatic<AndroidJavaObject>("createChooser", intent, "分享图片");
|
||
|
||
currentActivity.Call("startActivity", chooser);
|
||
|
||
RuntimeLog.Instance?.AddLog("分享Intent已启动");
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
RuntimeLog.Instance?.AddLog($"分享失败: {ex.Message}\n{ex.StackTrace}");
|
||
Debug.LogError($"分享失败: {ex.Message}");
|
||
}
|
||
}
|
||
//刷新图片,显示到相册中
|
||
void ScanFile(string[] path)
|
||
{
|
||
using (AndroidJavaClass PlayerActivity = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
|
||
{
|
||
AndroidJavaObject playerActivity = PlayerActivity.GetStatic<AndroidJavaObject>("currentActivity");
|
||
using (AndroidJavaObject Conn = new AndroidJavaObject("android.media.MediaScannerConnection", playerActivity, null))
|
||
{
|
||
Conn.CallStatic("scanFile", playerActivity, path, null, null);
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取当前年月日时分秒,如201803081916
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
string GetCurTime()
|
||
{
|
||
return DateTime.Now.Year.ToString() + DateTime.Now.Month.ToString() + DateTime.Now.Day.ToString()
|
||
+ DateTime.Now.Hour.ToString() + DateTime.Now.Minute.ToString() + DateTime.Now.Second.ToString();
|
||
}
|
||
public void OffSelectPlane()
|
||
{
|
||
try
|
||
{
|
||
RuntimeLog.Instance?.AddLog("\n=== 关闭预览界面 ===");
|
||
|
||
// 重新检查并获取 header
|
||
if (header == null)
|
||
{
|
||
RuntimeLog.Instance?.AddLog("header为空,尝试重新查找");
|
||
header = GameObject.Find("Header");
|
||
}
|
||
|
||
// 显示 header
|
||
if (header != null)
|
||
{
|
||
header.SetActive(true);
|
||
RuntimeLog.Instance?.AddLog("Header 已显示");
|
||
}
|
||
else
|
||
{
|
||
RuntimeLog.Instance?.AddLog("错误: 无法找到 Header 对象");
|
||
}
|
||
|
||
// 恢复按钮状态
|
||
SetbuttonGameObject();
|
||
RuntimeLog.Instance?.AddLog("按钮状态已恢复");
|
||
|
||
// 关闭预览面板
|
||
if (selectPlane != null)
|
||
{
|
||
selectPlane.SetActive(false);
|
||
RuntimeLog.Instance?.AddLog("预览面板已关闭");
|
||
}
|
||
|
||
RuntimeLog.Instance?.AddLog("=== 预览界面关闭完成 ===");
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
RuntimeLog.Instance?.AddLog($"关闭预览界面失败: {ex.Message}");
|
||
Debug.LogError($"关闭预览界面失败: {ex.Message}");
|
||
}
|
||
}
|
||
|
||
public void DeleteScreenshot(string name)
|
||
{
|
||
if (string.IsNullOrEmpty(name))
|
||
{
|
||
Debug.LogWarning("文件名不能为空");
|
||
return;
|
||
}
|
||
|
||
string fullPath = path + "/Pictures/Screenshots/" + name;
|
||
if (File.Exists(fullPath))
|
||
{
|
||
File.Delete(fullPath);
|
||
Debug.Log("图片已删除: " + fullPath);
|
||
}
|
||
else
|
||
{
|
||
Debug.LogWarning("文件不存在: " + fullPath);
|
||
}
|
||
}
|
||
|
||
private void SetbuttonGameObject()
|
||
{
|
||
try
|
||
{
|
||
RuntimeLog.Instance?.AddLog("恢复UI状态");
|
||
|
||
if (shuiYin != null)
|
||
{
|
||
shuiYin.SetActive(false);
|
||
}
|
||
|
||
foreach (var item in buttonGameObject)
|
||
{
|
||
if (item != null)
|
||
{
|
||
item.SetActive(true);
|
||
}
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
RuntimeLog.Instance?.AddLog($"恢复UI状态失败: {ex.Message}");
|
||
}
|
||
}
|
||
private void OffbuttonGameObject()
|
||
{
|
||
try
|
||
{
|
||
RuntimeLog.Instance?.AddLog("隐藏UI元素");
|
||
|
||
if (shuiYin != null)
|
||
{
|
||
shuiYin.SetActive(true);
|
||
}
|
||
|
||
foreach (var item in buttonGameObject)
|
||
{
|
||
if (item != null)
|
||
{
|
||
item.SetActive(false);
|
||
}
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
RuntimeLog.Instance?.AddLog($"隐藏UI元素失败: {ex.Message}");
|
||
}
|
||
}
|
||
} |