It seems that as of Android 2.2, there is a new feature for sending crash reports, as mentioned in the links:
http://www.androidcentral.com/new-android-app-crash-report-tool-already-and-running
http://android-developers.blogspot.com/2010/05/google-feedback-for-android.html
http://developer.android.com/sdk/android-2.2-highlights.html
http://www.youtube.com/watch?v=o8unC9bA4O8
How do I use this feature? Is it automatic for each application downloaded from the market (aka Google Play Store)?
Where can I find more info about this feature?
Also, is it possible to customize what is being sent, perhaps by using DefaultExceptionHandler, and put our own description of the crash?
NOTE: i know that there are plenty of tools for sending crash reports (like ACRA) , but i wish to check first if it's possible to use what's already given.
EDIT: I've succeeded modifying the exception that is passed further, hoping that this will also change the report that is sent to the developer website of Google.
Here's a sample code that is relevant for this:
private static class DefaultExceptionHandler implements java.lang.Thread.UncaughtExceptionHandler
...
#Override
public void uncaughtException(Thread t, Throwable e)
{
final StackTraceElement[] exceptionStackTrace = e.getStackTrace();
Exception exception = new Exception("my new exception!", e);
final StackTraceElement[] newExceptionStackTrace = new StackTraceElement[exceptionStackTrace.length + 1];
System.arraycopy(exceptionStackTrace, 0, newExceptionStackTrace, 1, exceptionStackTrace.length);
newExceptionStackTrace[0] = new StackTraceElement("TEST CLASS", "TEST METHOD", "TEST FILE", 0);
exception.setStackTrace(newExceptionStackTrace);
_defaultUEH.uncaughtException(t, exception); //this will hopefully call the default handling of the exception for reporting
}
What you have described sounds like the build in feature, and as far as I know, you cannot customize this. The data will be send to the googlePlay dev account which uploaded the app. I have seen customizations made by Sense, or Custom Roms. The only way to get your own Logs, is to use the DefaultErrorHandler you mentioned. As a good practice I would check, if you can catch the error yourself, (maybe log it somewhere). If not I would rethrow this error, to give the user a chance to give you hints , what he has done
Related
I would like to get a object dump additionally sent during a crashlytics exception logging. So for example lets say there is a nullPointerException that occurs. i'd like to additionally add a large object which would be my model and include that in the stack trace area in crashlytics. this way when i see the stacktrace i can also view the model information from the dump. How would i send this info in additional to the usual crashlytics logging ? Here is what i have so far:
try{
//....
throw new NullPointerException("my cool msg");
}
catch(Exception e){
Crashlytics.setInt("priority", 4);
Crashlytics.setString("tag", "mytag");
Crashlytics.setString("message", Model.toString());
Crashlytics.logException(e);
}
What is occuring now is that nothing is appearing. but if i comment out the setString for "message" then i get a stacktrace with the message "my cool msg".
UPDATE: I even tried Crashlytics.log(Model.toString()); but that shows nothing on crashlytics. i am setting up crashlytics from Application subclass in onCreate like this: Fabric.with(this, new Crashlytics());
from the cashlytics docs i found this:
To make sure that sending crash reports has the smallest impact on your user’s devices, Crashlytics logs have a maximum size of 64 KB. When a log exceeds 64 KB, the earliest logged values will be dropped in order to maintain this threshold.
this could be my issue. checking my size now...
adjusting the size of the payload did not work. i made the payload 9 characters but still its not appearing.
UPDATE:
Lets start again but more simply. why does the following not work for me ?
try{
//....
throw new NullPointerException("my cool msg");
}
catch(Exception e){
Crashlytics.setInt("priority", 4);
Crashlytics.setString("tag", "mytag");
Crashlytics.setString("message", "");
Crashlytics.logException(e);
}
What happens here is indeed a stacktrace appears in crasylytics dashboard with the words "my cool message" but there is nothing about priority, tag or message. Only the stacktrace is appearing. should there
not be entries there with these headings or something ?
AFter clicking on the green "view all sessions" button i was able to see the custom information. they could have made it more obvious.
and also from the docs it seems the non-fatal exceptions are batched and sent the next time the app launches:
Crashlytics processes exceptions on a dedicated background thread, so the performance impact to your app is minimal. To reduce your users’ network traffic, Crashlytics batches logged exceptions together and sends them the next time the app launches.
I tried to send a custom data with acra(and without crashing my app) with these 2 lines
ACRA.getErrorReporter().putCustomData("myKey", "myValue");
ACRA.getErrorReporter().handleException(null);
But in the report that I received was just:
Report requested by developer
The problem is that in my report there was no "myKey" or "myValue". How can I fix that? Maybe the problem is that I didn't include some specific Report Fields?
After that I tried with just
ACRA.getErrorReporter().handleException(null);
and it worked as with 2 lines above??
ACRA is designed to capture unhandled exceptions. It also provides functionality to silently send handled exceptions. Sending null is way outside its design parameters.
Try sending an actual exception.
I did a little workaround to group specific messages sent by it's exception. I introduced "FakeException" and removed stack trace so the message would be smaller.
public class FakeException extends Exception {
#Override
public Throwable fillInStackTrace() {
return null;
}
#Override
public void setStackTrace(StackTraceElement[] trace) {
super.setStackTrace(null);
}
}
Now You can create another Exception that extends FakeException and do something like this:
public void SendUserReport(String reportText){
ACRA.getErrorReporter().putCustomData(USER_REPORT_CONTENT_TAG, reportText);
ACRA.getErrorReporter().handleSilentException(new NotificationFromUserFakeException());
ACRA.getErrorReporter().removeCustomData(USER_REPORT_CONTENT_TAG);
}
The following picture shows this report in Acralyzer (awesome software, definitely use it).
Is there a way to view the log on a tablet running 4.4? I've downloaded several apps like aLogCat and none of them show what my app writes out with S.o.p or Log.d. I have an intermittent bug that gives the Unfortunately appname has stopped message.Is there any way to view the log after this event without having to connect to a PC and use the adb program?
What other ways are there to get debug output? Would trapping the System.out and System.err classes get the stack trace?
Thanks,
Norm
You're focussing on tring to read out logcat, but there are better solutions for reading crash logs. My personal preference is Crashlytics, which automatically logs fatal exceptions and provides mechanisms for logging other messages.
The way all these crash reporters work, is by defining a UncaughtExceptionHandler:
Thread.setDefaultUncaughtExceptionHandler(
new MyUncaughtExceptionHandler(this));
If you prefer to use your own solution, you may want to look into using this. See this related question for more details.
Is there a way to view the log on a tablet running 4.4?
No, sorry. An app can only see its own log messages, not those from other apps. Hence, a third-party log viewer cannot see your app's messages.
Is there any way to view the log after this event without having to connect to a PC and use the adb program?
Use any standard crash management library, like ACRA, or services like Crashlytics, BugSense, etc.
The AIDE Application (Android Integrated Development Environment) allows one to develop android Apps directly on android device.
One particular feature is to read the logcat.
You can get it here https://play.google.com/store/apps/details?id=com.aide.ui
Here's the code I've put in the program. It seems to work:
// Define inner class to handle exceptions
class MyExceptionHandler implements Thread.UncaughtExceptionHandler {
public void uncaughtException(Thread t, Throwable e){
java.util.Date dt = new java.util.Date();
String fn = LogFilePathPfx + "exception_" + sdf.format(dt) + ".txt";
try{
PrintStream ps = new PrintStream( fn );
e.printStackTrace(ps);
ps.close();
System.out.println("wrote trace to " + fn);
e.printStackTrace(); // capture here also???
SaveStdOutput.stop(); // close here vs calling flush() in class
}catch(Exception x){
x.printStackTrace();
}
lastUEH.uncaughtException(t, e); // call last one Gives: "Unfortunately ... stopped" message
return; //???? what to do here
}
}
lastUEH = Thread.getDefaultUncaughtExceptionHandler(); // save previous one
Thread.setDefaultUncaughtExceptionHandler(new MyExceptionHandler());
In my Android application I utilize setDefaultUncaughtExceptionHandler to store information about unhandled exceptions locally on a user device. After some feedback I suspect that this code prevents the built-in Google's error-reporting feature from work, because I do not see error reports in the developer console, while exceptions are reported by users. Their devices are well past 2.2, where the error-reporting was introduced. Could it be that specific device with, say, 4.0.3 does not support this feature? If yes, how can I detect this programmatically?
I can't find information regarding this in Android documentation. I'd like both standard error-reporting and my custom handling work together. In my custom exception handler I call Thread.getDefaultUncaughtExceptionHandler() to get default handler, and in my implementation of uncaughtException I propagate exception to this default handler as well.
I first tried calling System.exit(1); as mentioned in this SO answer, but that didn't work.
Finally solved it by calling the uncaughtException(Thread thread, Throwable ex) again on Androids default UncaughtExceptionHandler (found it by checking the ACRA source code.
Example Activity
public class MainActivity extends Activity implements Thread.UncaughtExceptionHandler {
private Thread.UncaughtExceptionHandler _androidUncaughtExceptionHandler;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
_androidUncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(this);
// Rest onCreate
setContentView(R.layout.main_activity);
}
//#Override
public void uncaughtException(Thread thread, Throwable ex) {
try {
// Do your stuff with the exception
} catch (Exception e) {
/* Ignore */
} finally {
// Let Android show the default error dialog
_androidUncaughtExceptionHandler.uncaughtException(thread, ex);
}
}
}
Yes, this will stop the inbuilt error report. The user is given a dialog when your app crashes, with an option to report the error via Google Play. However, if you use setDefaultUncaughtExceptionHandler() then the exception is handled within your app, and no option is given to report it.
I recommend that you integrate ACRA into your project, as it allows you to easily receive error reports upon crashes.
I'm using the android crittercism library and trying to send a report when I catched an error level exception.
But I can't find the documentation on how to do that. Is this even possible? If so, how?
They temporarily moved the feature into beta. If you e-mail support they'll enable your account for handled exceptions. Below is the sample Android code:
try
{
throw new Exception("Exception Reason");
}
catch (Exception exception)
{
Crittercism.logHandledException(exception);
}
Just in case you need it, here is sample code on iOS:
#try {
[NSException raise:NSInvalidArgumentException
format:#"Foo must not be nil"];
} #catch (NSException *exception) {
// Pass it on to us!
[Crittercism logHandledException:exception]
}
I'm the co-founder and CTO of Crittercism. If you send me an awesome email, I can enable it for your account. I'm rob[at] :)
Crittercism.logHandledException(new Throwable("test"));
You don't actually have to throw the Exception (or Throwable, in this case).
It will appear under "Handled Exceptions" on Crittercism website.