c# - 如何将 android Unity 错误和调试日志导出到文件?

标签 c# android unity3d virtual-reality samsung-galaxy-gear

我正在尝试为 Samsung Gear VR(与 Samsung Galaxy S8)开发一个应用程序,因为它需要我拔出 USB 数据线才能将手机插入 Gear VR 设备,这不允许我进行 USB 调试。

如何将错误和调试消息导出到我可以阅读的文件中,以便找出问题所在?

到目前为止,研究表明 android Unity 播放器不会保存到日志文件,而其他平台会保存,而 adb 是进行 USB 调试的方式...只有我不能为 Gear 这样做。

最佳答案

How to export android Unity error and debug logs to file?

那还不存在。你必须自己做一个。

1.订阅Unity Log事件:

Application.logMessageReceived += LogCallback;

2.将它们存储在列表中。当应用程序即将退出时,序列化为 json 并使用 File.WriteAllBytes 保存。

将其保存到的路径是 Application.persistentDataPath。参见 this该帖子显示了在 Unity 中的任何构建中可以找到该路径的位置。

下面是一个示例脚本,它在应用程序即将退出时读取日志并保存它。此外,它还能够通过电子邮件向您发送日志数据。 这需要来自 thisDataSaver 类发布。请注意,电子邮件是在应用程序下次重新打开时发送的,而不是在它退出时发送的。

using System.Collections.Generic;
using UnityEngine;

using System.IO;
using System.Net;
using System.Net.Mail;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System;
using System.Text;

public class LogSaverAndSender : MonoBehaviour
{
    public bool enableSave = true;
    public bool enableMailing = true;

    public string yourEmail = "fromemail@gmail.com";
    public string yourEmailPassword = "password";
    public string toEmail = "toemail@gmail.com";


    [Serializable]
    public struct Logs
    {
        public string condition;
        public string stackTrace;
        public LogType type;

        public string dateTime;

        public Logs(string condition, string stackTrace, LogType type, string dateTime)
        {
            this.condition = condition;
            this.stackTrace = stackTrace;
            this.type = type;
            this.dateTime = dateTime;
        }
    }

    [Serializable]
    public class LogInfo
    {
        public List<Logs> logInfoList = new List<Logs>();
    }

    LogInfo logs = new LogInfo();

    void OnEnable()
    {
        //Email last saved log
        if (enableMailing)
        {
            mailLog();
        }

        //Subscribe to Log Event
        Application.logMessageReceived += LogCallback;
    }

    //Called when there is an exception
    void LogCallback(string condition, string stackTrace, LogType type)
    {
        //Create new Log
        Logs logInfo = new Logs(condition, stackTrace, type, DateTime.Now.ToString("yyyy-MM-ddTHH:mm:sszzz"));

        //Add it to the List
        logs.logInfoList.Add(logInfo);
    }

    void mailLog()
    {
        //Read old/last saved log
        LogInfo loadedData = DataSaver.loadData<LogInfo>("savelog");
        string date = DateTime.Now.ToString("yyyy-MM-ddTHH:mm:sszzz");

        //Send only if there is something to actually send
        if (loadedData != null && loadedData.logInfoList != null

            && loadedData.logInfoList.Count > 0)
        {

            Debug.Log("Found log to send!");

            //Convert to json
            string messageToSend = JsonUtility.ToJson(loadedData, true);

            string attachmentPath = Path.Combine(Application.persistentDataPath, "data");
            attachmentPath = Path.Combine(attachmentPath, "savelog.txt");

            //Finally send email
            sendMail(yourEmail, yourEmailPassword, toEmail, "Log: " + date, messageToSend, attachmentPath);

            //Clear old log
            DataSaver.deleteData("savelog");
        }
    }

    void sendMail(string fromEmail, string emaiPassword, string toEmail, string eMailSubject, string eMailBody, string attachmentPath = null)
    {
        try
        {
            MailMessage mail = new MailMessage();

            mail.From = new MailAddress(fromEmail);
            mail.To.Add(toEmail);
            mail.Subject = eMailSubject;
            mail.Body = eMailBody;

            if (attachmentPath != null)
            {
                System.Net.Mail.Attachment attachment = new System.Net.Mail.Attachment(attachmentPath);
                mail.Attachments.Add(attachment);
            }

            SmtpClient smtpClient = new SmtpClient();
            smtpClient.Host = "smtp.gmail.com";
            smtpClient.Port = 587;
            smtpClient.DeliveryMethod = SmtpDeliveryMethod.Network;
            smtpClient.Credentials = new System.Net.NetworkCredential(fromEmail, emaiPassword) as ICredentialsByHost;
            smtpClient.EnableSsl = true;
            ServicePointManager.ServerCertificateValidationCallback =
                delegate (object s, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
                { return true; };
            smtpClient.Send(mail);
        }
        catch (Exception e) { }
    }

    void OnDisable()
    {
        //Un-Subscribe from Log Event
        Application.logMessageReceived -= LogCallback;
    }

    //Save log  when focous is lost
    void OnApplicationFocus(bool hasFocus)
    {
        if (!hasFocus)
        {
            //Save
            if (enableSave)
                DataSaver.saveData(logs, "savelog");
        }
    }

    //Save log on exit
    void OnApplicationPause(bool pauseStatus)
    {
        if (pauseStatus)
        {
            //Save
            if (enableSave)
                DataSaver.saveData(logs, "savelog");
        }
    }
}

关于c# - 如何将 android Unity 错误和调试日志导出到文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46272657/

相关文章:

java - 将广告单元和应用程序 ID(我的 Admob 帐户广告)替换为测试(广告和应用程序 ID)后,Google Admob 广告未显示

android - 按钮上的长文本弄乱了 GridLayout 行

android - 使用 Unity 发送 TCP

c# - 在 Windows 窗体中访问另一个窗体上的控件的最佳方法?

c# - 从 Webkit 浏览器和 .NET 20 的 Java 脚本调用 C# 函数

Android Studio 3.0迁移AAPT2报错

unity3d - 如何通过在 Unity(编辑器模式)中单击来选择没有渲染器的对象?

c# - 在 Unity 中将 bool 值从一个场景保存到另一个场景

c# - 来自列表<object> 的组合框 DisplayMemberPath

c# - 如何从 Visual C# 2013 中的另一个(引用)项目访问表单组件?