Is there any way of retrieving log messages from an Android handset.
I'm building an application which uses the GPS of my HTC Hero. I can run and debug the application from eclipse but this isn't a good use case of GPS, sat at my desk.
When I fire the app up when I am walking around, I get an intermittent exception. Is there anyway I can output these exceptions to a text file on the SD card or output calls to Log.x("")
to a text file so that I can see wh开发者_如何学Goat the exception is.
Thanks
EDIT : Solution
Here is the code I finally went with...
Thread.currentThread().setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread thread, Throwable ex) {
PrintWriter pw;
try {
pw = new PrintWriter(
new FileWriter(Environment.getExternalStorageDirectory()+"/rt.log", true));
ex.printStackTrace(pw);
pw.flush();
pw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
});
I had to wrap the line
pw = new PrintWriter(new FileWriter(Environment.getExternalStorageDirectory()+"/rt.log", true));
in a try/catch as Eclipse would not let me compile the app. It kept saying
Unhandled exception type IOException 1 quick fix Sorround with try/catch
So I did and it all works which is fine by me but it does make me wonder what Eclipse was on about...
You could use Thread.setUncaughtExceptionHandler()
to catch the Exceptions.
Writing to SD Card is as simple as retrieving the directory for the card using Environment.getExternalStorageDirectory()
and creating a file there.
File f = new File(Environment.getExternalStorageDirectory(),filename);
You will need to give you app the correct permission to write to the SD Card by adding this to your Manifest:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Log4j or slf4j can also be used as logging frameworks in Android together with logcat. See the project android-logging-log4j. Configuring logging to a (rotating) file(s) is very easy.
static {
final LogConfigurator logConfigurator = new LogConfigurator();
logConfigurator.setFileName(Environment.getExternalStorageDirectory() + "myapp.log");
logConfigurator.setRootLevel(Level.DEBUG);
// Set log level of a specific logger
logConfigurator.setLevel("org.apache", Level.ERROR);
logConfigurator.configure();
}
You could take a look at microlog4android. They have a solution ready to log to a file.
https://github.com/johanlkarlsson/microlog4android
I tried both options above (microlog4android & android-logging-log4j) and they were a struggle to try to get working. Once they compiled fine then I would get Runtime java.lang.NoClassDefFoundError.
So then I stumbled on logback-android ... also found here http://logback.qos.ch/
It has much better instructions and I got it working in a couple hours.
This appears to be the best logging solution for Android.
Use slf4-android lib created by BrightInventions. It's simple implementation of slf4j api using android java.util.logging.*.
Features:
- logging to file out of the box
- logging to any other destination by
LoggerConfiguration.configuration().addHandlerToLogger
- shake your device to send logs with screenshot via email
- really small, it tooks only ~55kB
slf4android is maintained mainly by @miensol.
Read more about slf4android on our blog:
- Introducing slf4android
- Integrate slf4android with Crashlytics
Based on @Greg B solution and @JPM question in the comment, I made this static method in a seperate class and each time you instanciate a new thread, call it.
package com.stackoverflow.
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import android.os.Environment;
public class UnhandledExceptionHandler {
public static void setUndhandledException(Thread thread) {
if (thread.getUncaughtExceptionHandler() == null) {
Thread.currentThread().setUncaughtExceptionHandler(
new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread thread,
Throwable ex) {
PrintWriter pw;
try {
pw = new PrintWriter(new FileWriter(Environment
.getExternalStorageDirectory()
+ "/rt-networkandgps"
+ "/gpx/"
+ thread.getId() + ".log", true));
ex.printStackTrace(pw);
pw.flush();
pw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
}
}
Call it from anythread like this,
UnhandledExceptionHandler.setUndhandledException(Thread.currentThread());
精彩评论