我正在尝试为三星 Gear VR(使用三星 Galaxy S8)开发一个应用程序,因为它需要我拔出 USB 电缆才能将手机插入 Gear VR 设备,这不允许我做 USB调试。
如何将错误和调试消息导出到我可以阅读的文件中以找出问题所在?
到目前为止,研究表明 android Unity 播放器不会保存到日志文件,而其他平台会这样做,而 adb 是 USB 调试的方式......只有我不能为 Gear 这样做。
我正在尝试为三星 Gear VR(使用三星 Galaxy S8)开发一个应用程序,因为它需要我拔出 USB 电缆才能将手机插入 Gear VR 设备,这不允许我做 USB调试。
如何将错误和调试消息导出到我可以阅读的文件中以找出问题所在?
到目前为止,研究表明 android Unity 播放器不会保存到日志文件,而其他平台会这样做,而 adb 是 USB 调试的方式......只有我不能为 Gear 这样做。
如何将 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");
}
}
}
如果您想更好地理解代码,请参阅我的教程: 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);
}
}
}