[英]Android Writing Logs to text File
我正在嘗試使用我的此代碼將日志寫入 Android 文件上的自定義 Log.txt 文件,但此方法創建了文件但不包含任何內容。 基本上我想閱讀文件的先前內容,然后將我的數據附加到現有內容中。
代碼如下:
public static void write(String str)
{
InputStream fileInputStream = null;
FileOutputStream fileOutpurStream = null;
try
{
fileInputStream = new FileInputStream(file);
fileOutpurStream = new FileOutputStream(file);
if(file.exists())
{
int ch = 0;
int current = 0;
StringBuffer buffer = new StringBuffer();
while((ch = fileInputStream.read()) != -1)
{
buffer.append((char) ch);
current++;
}
byte data[]=new byte[(int)file.length()];
fileInputStream.read(data);
fileOutpurStream.write(data);
fileOutpurStream.write(str.getBytes(),0,str.getBytes().length);
fileOutpurStream.flush();
}
else
{
file.createNewFile();
fileOutpurStream.write(str.getBytes(),0,str.getBytes().length);
fileOutpurStream.flush();
}
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
try
{
fileInputStream.close();
fileOutpurStream.flush();
fileOutpurStream.close();
fileOutpurStream = null;
fileInputStream = null;
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
希望這可以幫助...
public void appendLog(String text)
{
File logFile = new File("sdcard/log.file");
if (!logFile.exists())
{
try
{
logFile.createNewFile();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try
{
//BufferedWriter for performance, true to set append to file flag
BufferedWriter buf = new BufferedWriter(new FileWriter(logFile, true));
buf.append(text);
buf.newLine();
buf.close();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
對於一般 Java 日志記錄和 Android 日志記錄的新手
在 Android 中登錄到 txt 的一些選項如下
logcat -f
登錄到文件。 請注意,從 Android 4.2 開始,READ_LOGS 權限沒有任何影響,每個應用程序(除非手機已 root)只能讀取自己的日志。 這里的缺點是 logcat 緩沖區是循環的並且有大小限制。 您可能無法獲得較早的日志。將Log4j與android-logging-log4j 一起使用。 android-logging-log4j 有什么作用? 它通過提供兩個功能使 Log4j 在 Android 中更易於使用。
下面的簡單例子。 請注意,下面示例中的logger
對象是返回的 Log4j 對象,而不是 android-logging-log4j 類。 所以android-logging-log4j只用於配置Log4j。
在 Android 中使用 Log4j 的步驟。
將log4j-1.2.x.jar和android-logging-log4j-1.0.3.jar 添加到 libs 文件夾。
僅在使用外部存儲時添加權限<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
編寫Log4j
輔助類
package com.example.logger; import android.os.Environment; import de.mindpipe.android.logging.log4j.LogConfigurator; public class Log4jHelper { private final static LogConfigurator mLogConfigrator = new LogConfigurator(); static { configureLog4j(); } private static void configureLog4j() { String fileName = Environment.getExternalStorageDirectory() + "/" + "log4j.log"; String filePattern = "%d - [%c] - %p : %m%n"; int maxBackupSize = 10; long maxFileSize = 1024 * 1024; configure( fileName, filePattern, maxBackupSize, maxFileSize ); } private static void configure( String fileName, String filePattern, int maxBackupSize, long maxFileSize ) { mLogConfigrator.setFileName( fileName ); mLogConfigrator.setMaxFileSize( maxFileSize ); mLogConfigrator.setFilePattern(filePattern); mLogConfigrator.setMaxBackupSize(maxBackupSize); mLogConfigrator.setUseLogCatAppender(true); mLogConfigrator.configure(); } public static org.apache.log4j.Logger getLogger( String name ) { org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger( name ); return logger; } }
在活動類
org.apache.log4j.Logger log= Log4jHelper.getLogger( "YourActivity" ); log.error("Error"); log.info("Info"); log.warn("Warn");
示例源。 請注意,從頭開始重寫的 log4j 2.x(改進的功能)不能與 log4j 1.x 向后兼容。 因此,您必須將 log4j 1.2.x jar 與 android-logging-log4j jar 一起使用。 我能夠登錄到應用程序內部文件,然后使用setReadable(true, false)
通過電子郵件發送文件
microlog4android 對我有用,但文檔很差。 他們需要添加的只是一個快速入門教程。
這是我找到的快速教程。
在主活動中添加以下靜態變量:
private static final Logger logger = LoggerFactory.getLogger();
將以下內容添加到您的onCreate()
方法中:
PropertyConfigurator.getConfigurator(this).configure();
創建一個名為microlog.properties
的文件並將microlog.properties
存儲在assets
目錄中
編輯microlog.properties
文件如下:
microlog.level=DEBUG microlog.appender=LogCatAppender;FileAppender microlog.formatter=PatternFormatter microlog.formatter.PatternFormatter.pattern=%c [%P] %m %T
添加這樣的日志語句:
logger.debug("M4A");
為每個類創建一個記錄器對象,如 1) 中指定的那樣
6.您可以添加以下權限:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
這是教程的來源
警告:我可能完全誤解了你,但如果你想要的只是一個日志文件,為什么要出汗呢?
把它放在一個 bat 文件中(改變你的工具目錄的路徑,你的appname當然是你的應用程序的名字):
cd "C:\devAndroid\Software\android-sdk-windows-1.6_r1\android-sdk-windows-1.6_r1\tools"
adb logcat -v time ActivityManager:W yourappname:D *:W >"C:\devAndroid\log\yourappname.log"
然后在你的代碼中做類似的事情:
Log.d("yourappname", "Your message");
要創建日志,請連接 USB 電纜並運行您的 bat 文件。
問候
使用slf4android庫。
這是使用 android java.util.logging.* 的slf4j api的簡單實現。
特征:
LoggerConfiguration.configuration().addHandlerToLogger
記錄到任何其他目的地slf4android 主要由@miensol維護。
在我們的博客上閱讀有關 slf4android 的更多信息:
這可能會晚,但希望這可能會有所幫助..試試這個....
public void writefile()
{
File externalStorageDir = Environment.getExternalStorageDirectory();
File myFile = new File(externalStorageDir , "yourfilename.txt");
if(myFile.exists())
{
try
{
FileOutputStream fostream = new FileOutputStream(myFile);
OutputStreamWriter oswriter = new OutputStreamWriter(fostream);
BufferedWriter bwriter = new BufferedWriter(oswriter);
bwriter.write("Hi welcome ");
bwriter.newLine();
bwriter.close();
oswriter.close();
fostream.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
else
{
try {
myFile.createNewFile();
}
catch (IOException e)
{
e.printStackTrace();
}
}
這里bfwritter.newline
將您的文本寫入文件。 並添加權限
<uses-permission android:name = "android.permission.WRITE_EXTERNAL_STORAGE"/>
在您的清單文件中沒有失敗。
你應該看看microlog4android。 他們有一個解決方案可以記錄到文件中。
我以命令行方式使用以下代碼解決了這個問題:
File outputFile = new File("pathToFile");
Runtime.getRuntime().exec("logcat -c");
Runtime.getRuntime().exec("logcat -v time -f " + outputFile.getAbsolutePath())
其中“時間”選項為日期、調用時間、優先級/標簽和發出消息的進程的 PID 添加元數據字段詳細信息。
然后在您的代碼中執行與此類似的操作(使用 android.util.Log):
Log.d("yourappname", "Your message");
我創建了一個簡單的輕量級類(大約 260 LoC),它使用基於文件的日志記錄擴展了標准的 android.util.Log 實現:
每條日志消息都通過 android.util.Log 記錄並寫入設備上的文本文件。
你可以在github上找到它:
https://github.com/volkerv/FileLog
通常,在打開流之前您必須有一個文件句柄。 在 else 塊中的 createNewFile()之前,您有一個 fileOutputStream 句柄。 如果文件不存在,則流不會創建文件。
不是真正的android特定的,但是為此目的有很多IO。 如果您一個接一個地執行許多“寫入”操作怎么辦? 您將閱讀全部內容並編寫全部內容,這需要時間,更重要的是電池壽命。
我建議使用 java.io.RandomAccessFile,seek()'ing 到最后,然后 writeChars() 追加。 這將是更干凈的代碼,並且可能會更快。
經過長時間的調查,我發現:
android.util.Log
默認使用java.util.logging.Logger
""
logger
,使用LogManager.getLogManager().getLogger("")
獲取它的實例com.android.internal.logging.AndroidHandler
LogCat logger
實例com.android.internal.logging.AndroidHandler
僅將消息打印到 logcat,其級別高於java.util.logging.Level.INFO
例如 ( Level.INFO, Level.WARNING, Level.SEVERE, Level.OFF
) 所以要將日志寫入文件只是簡單的rootLogger
""
添加一個java.util.logging.FileHandler
:
class App : Application{
override fun onCreate() {
super.onCreate()
Log.d(TAG, printLoggers("before setup"))
val rootLogger = java.util.logging.LogManager.getLogManager().getLogger("")
val dirFile = destinationFolder
val file = File(dirFile,"logFile.txt")
val handler = java.util.logging.FileHandler(file.absolutePath, 5* 1024 * 1024/*5Mb*/, 1, true)
handler.formatter = AndroidLogFormatter(filePath = file.absolutePath)
rootLogger?.addHandler(handler)
Log.d(TAG, printLoggers("after setup"))
}
}
val destinationFolder: File
get() {
val parent =
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).absoluteFile
val destinationFolder = File(parent, "MyApp")
if (!destinationFolder.exists()) {
destinationFolder.mkdirs()
destinationFolder.mkdir()
}
return destinationFolder
}
class AndroidLogFormatter(val filePath: String = "", var tagPrefix: String = "") : Formatter() {
override fun format(record: LogRecord): String {
val tag = record.getTag(tagPrefix)
val date = record.getDate()
val level = record.getLogCatLevel()
val message = record.getLogCatMessage()
return "$date $level$tag: $message\n"
}
}
fun LogRecord.getTag(tagPrefix: String): String {
val name = loggerName
val maxLength = 30
val tag = tagPrefix + (if (name.length > maxLength) name.substring(name.length - maxLength) else name)
return tag
}
fun LogRecord.getDate(): String? {
return Date(millis).formatedBy("yyyy-MM-dd HH:mm:ss.SSS")
}
fun Date?.formatedBy(dateFormat: String): String? {
val date = this
date ?: return null
val writeFormat = SimpleDateFormat(dateFormat, Locale.getDefault()) //MM в HH:mm
return writeFormat.format(date)
}
fun LogRecord.getLogCatMessage(): String {
var message = message
if (thrown != null) {
message += Log.getStackTraceString(thrown)
}
return message
}
fun Int.getAndroidLevel(): Int {
return when {
this >= Level.SEVERE.intValue() -> { // SEVERE
Log.ERROR
}
this >= Level.WARNING.intValue() -> { // WARNING
Log.WARN
}
this >= Level.INFO.intValue() -> { // INFO
Log.INFO
}
else -> {
Log.DEBUG
}
}
}
fun LogRecord.getLogCatLevel(): String {
return when (level.intValue().getAndroidLevel()) {
Log.ERROR -> { // SEVERE
"E/"
}
Log.WARN -> { // WARNING
"W/"
}
Log.INFO -> { // INFO
"I/"
}
Log.DEBUG -> {
"D/"
}
else -> {
"D/"
}
}
}
fun getLoggerLevel(level: Int): Level {
return when (level) {
Log.ERROR -> { // SEVERE
Level.SEVERE
}
Log.WARN -> { // WARNING
Level.WARNING
}
Log.INFO -> { // INFO
Level.INFO
}
Log.DEBUG -> {
Level.FINE
}
else -> {
Level.FINEST
}
}
}
要在您的應用中打印所有記錄器,請使用:
Log.e(TAG, printLoggers("before setup"))
private fun printLoggers(caller: String, printIfEmpty: Boolean = true): String {
val builder = StringBuilder()
val loggerNames = LogManager.getLogManager().loggerNames
builder.appendln("--------------------------------------------------------------")
builder.appendln("printLoggers: $caller")
while (loggerNames.hasMoreElements()) {
val element = loggerNames.nextElement()
val logger = LogManager.getLogManager().getLogger(element)
val parentLogger: Logger? = logger.parent
val handlers = logger.handlers
val level = logger?.level
if (!printIfEmpty && handlers.isEmpty()) {
continue
}
val handlersNames = handlers.map {
val handlerName = it.javaClass.simpleName
val formatter: Formatter? = it.formatter
val formatterName = if (formatter is AndroidLogFormatter) {
"${formatter.javaClass.simpleName}(${formatter.filePath})"
} else {
formatter?.javaClass?.simpleName
}
"$handlerName($formatterName)"
}
builder.appendln("level: $level logger: \"$element\" handlers: $handlersNames parentLogger: ${parentLogger?.name}")
}
builder.appendln("--------------------------------------------------------------")
return builder.toString()
}
這個變體要短得多
try { final File path = new File( Environment.getExternalStorageDirectory(), "DBO_logs5"); if (!path.exists()) { path.mkdir(); } Runtime.getRuntime().exec( "logcat -d -f " + path + File.separator + "dbo_logcat" + ".txt"); } catch (IOException e) { e.printStackTrace(); }
你可以使用我寫的庫。 它非常易於使用:
將此依賴項添加到您的 gradle 文件中:
dependencies {
compile 'com.github.danylovolokh:android-logger:1.0.2'
}
在 Application 類中初始化庫:
File logsDirectory = AndroidLogger.getDefaultLogFilesDirectory(this);
int logFileMaxSizeBytes = 2 * 1024 * 1024; // 2Mb
try {
AndroidLogger.initialize(
this,
logsDirectory,
"Log_File_Name",
logFileMaxSizeBytes,
false
);
} catch (IOException e) {
// Some error happened - most likely there is no free space on the system
}
這是您使用庫的方式:
AndroidLogger.v("TAG", "Verbose Message");
這是檢索日志的方法:
AndroidLogger.processPendingLogsStopAndGetLogFiles(new AndroidLogger.GetFilesCallback() {
@Override
public void onFiles(File[] logFiles) {
// get everything you need from these files
try {
AndroidLogger.reinitAndroidLogger();
} catch (IOException e) {
e.printStackTrace();
}
}
});
這是包含更多信息的 github 頁面鏈接: https : //github.com/danylovolokh/AndroidLogger
希望能幫助到你。
log4j 上的許多以前版本現在都不起作用 (05/2019)。 但是您可以使用 Hyperlog - 我可以確認它有效。
將此行添加到您的依賴項和同步項目
implementation 'com.hypertrack:hyperlog:0.0.10'
創建一個新的應用程序類(創建一個新的 java 類並擴展應用程序)。 然后在 onCreate 方法中添加以下幾行:
HyperLog.initialize(this); HyperLog.setLogLevel(Log.VERBOSE); HyperLog.getDeviceLogsInFile(this);
更改清單文件以定義應用程序文件。
<application android:name=".AppClass" .....
不同的登錄方式:
HyperLog.d(TAG,"debug"); HyperLog.i(TAG,"information"); HyperLog.e(TAG,"error"); HyperLog.v(TAG,"verbose"); HyperLog.w(TAG,"warning"); HyperLog.a(TAG,"assert"); HyperLog.exception(TAG,"exception",throwable);
找到您的日志文件。 導航到
RootFolder/android/data/"appPackageName/LogFiles/
File logFile = new File(filename);
try {
Process process = Runtime.getRuntime().exec("logcat AndroidRuntime:E *:S
-f " + logFile);
}
catch ( Exception e )
{ Basic.Logger("Error Basic", "error "+e); }
試試這個在文件中寫入錯誤日志的代碼
public void appendLog(String text)
{
File logFile = new File("sdcard/log.file.txt");
if (!logFile.exists())
{
try
{
logFile.createNewFile();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try
{
//BufferedWriter for performance, true to set append to file flag
BufferedWriter buf = new BufferedWriter(new FileWriter(logFile, true));
buf.append(text);
buf.newLine();
buf.close();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.