4

我正在尝试为三星 Gear VR(使用三星 Galaxy S8)开发一个应用程序,因为它需要我拔出 USB 电缆才能将手机插入 Gear VR 设备,这不允许我做 USB调试。

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

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

4

2 回答 2

12

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

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

1.订阅Unity Log事件:

Application.logMessageReceived += LogCallback;

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

将其保存到的路径是Application.persistentDataPath. 请参阅这篇文章,其中显示了在 Unity 中的任何构建中可以找到路径的位置。

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

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");
        }
    }
}
于 2017-09-18T09:25:21.457 回答
-2

如果您想更好地理解代码,请参阅我的教程: android 文件教程

using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.UI;


public class UtilsMath : MonoBehaviour
{
    private string gpsFilePath;
    private void Start()
    {
      gpsFilePath = Application.persistentDataPath + "/logFilesGPSUnity.txt";

      //if you want to empty the file every time the app starts,
      // only delete and create a new one.

      // if gps file exists
      if (File.Exists(gpsFilePath))
      {
        //delete file
        try
        {
            File.Delete(gpsFilePath);
            Debug.Log("[Utils Script]: GPS File Log Deleted Successfully!");
        }
        catch (System.Exception e)
        {
            Debug.LogError("[Utils Script]: Cannot delete GPS File Log - Exception: " + e);
        }
      }
  }


/// <summary>
/// <para> Writes the string message into the logFilesGPSUnity.txt in the internal storage\android\data\com.armis.arimarn\files\</para>
/// You need to write a '\n' in the end or beginning of each message, otherwise, the message will be printed in a row.
/// </summary>
/// <param name="message">String to print in the file</param>
  public void WriteToFile(string message)
  {
    try
    {
        //create the stream writer to the specific file
        StreamWriter fileWriter = new StreamWriter(gpsFilePath, true);

        //write the string into the file
        fileWriter.Write(message);

        // close the Stream Writer
        fileWriter.Close();
    }
    catch (System.Exception e)
    {
        Debug.LogError("[Utils Script]: Cannot write in the GPS File Log - Exception: " + e);
    }
  }
}
于 2018-07-09T11:24:36.137 回答