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());
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'm working on an application with Xamarin (in Visual studio 2015) for android.
When I run my application in debug mode, sometime the application stop with message "MyApplication has stopped".
I've added this code in MainActivity :
// Catch Exception
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
AndroidEnvironment.UnhandledExceptionRaiser += AndroidEnvironment_UnhandledExceptionRaiser;
I added breakpoints add log in both functions, but I see no traces in log and the breakpoints are not reached.
How can I debug this kind of problem ?
You need to debug your application through a persistent logger i.e. adb logcat. Sadly registering an unhandled exception handler does not guarantee it will be a "catch-all" as it might never reach that point. So you will need a combination of both adb logcat and Console.WriteLine for these types of issues. Please take the following note into account when you want to see what's going on within this handler, but also make use of adb logcat to see the reason of the crash in the first place.
/// <summary>
/// When app-wide unhandled exceptions are hit, this will handle them. Be aware however, that typically
/// android will be destroying the process, so there's not a lot you can do on the android side of things,
/// but your xamarin code should still be able to work. so if you have a custom err logging manager or
/// something, you can call that here. You _won't_ be able to call Android.Util.Log, because Dalvik
/// will destroy the java side of the process.
/// </summary>
protected void HandleUnhandledException (object sender, UnhandledExceptionEventArgs args)
{
Exception e = (Exception) args.ExceptionObject;
// log won't be available, because dalvik is destroying the process
//Log.Debug (logTag, "MyHandler caught : " + e.Message);
// instead, your err handling code shoudl be run:
Console.WriteLine ("========= MyHandler caught : " + e.Message);
}
https://github.com/xamarin/monodroid-samples/blob/fb9d4ed266bdf68bb1f9fa9933130b285712ec82/AdvancedAppLifecycleDemos/HandlingCrashes/App.cs
Try it: Disabled "Use Shared Runtime" in Android build options. If it not helped try - disable "Use fast deplayment".
In Eclipse, I notice that Logcat only retains a few dozen entries and deletes the older ones as soon as a new one come in. Is there a way to prevent this? I need my app to run for a long time and not lose any entries because my app eventually hangs or crashes after a few days, and I want to see if something in Logcat has been recorded.
I am not sure if this is the most elegant solution to the problem, but you can always increase the LogCat message size in Eclipse.
Window -> Preferences -> Android -> LogCat -> Maximum number of LogCat messages to buffer
The default is 5000, I believe. You can set it to be very high if you are planning to run your application for a long time.
i think you need to increase this show image
Here's a better solution:
Set the Default Uncaught Exception Handler. Whenever the app crashes, this will be called with the exception. Simply write a log entry saying it crashed then dump the logcat to a file. Finally, make sure you re-throw the exception to make sure the app crashes and funky things don't happen. Note: This is per thread, keep that in mind.
Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() {
#Override
public void uncaughtException(Thread thread, Throwable ex) {
Log.e("TAG", "---My app crashed just now---", ex);
//TODO: Dump logcat to file
throw new RuntimeException(ex);
}
});
if you want to keep your app running for days.. its better you capture your logs from adb shell.
the common shell command would be :
logcat -c \\ to clear previous logs
logcat -v time>yourLogs.txt & \\ to capture fresh logs
I have created an application that extensively requires user inputs and interaction and even though I have made sure that I test and catch every possible case that might throw an error I want to be able to create a mechanism that traces the error in case my application crashes on the field.
I want to be able to record the entire flow right from a button click till whatever the user might be selecting or the navigation between the pages in a log file such that in case my application crashes I'm able to study the trace file later and know exactly where the error occurred.
I'm very new to this sort of programming and therefore any pointers on the above will be very helpful! Thank you in advance :]
PS: I'm not even sure whether what im referring to will be correctly called a "log trace" or not so any edit is welcome. :)
EDIT : I also want to be able to save the error report generated and send it to a particular id (similar to 'send an error report to xyz).
UPDATE :
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
try {
File myFiles = new File("/sdcard/ScanApp");
if(!myFiles.exists())
{
myFiles.mkdirs();
}
File myFile = new File("sdcard/ScanApp/log.txt");
myFile.createNewFile();
myFile.delete();
myFile.createNewFile();
String cmd = "logcat -d -v time -f "+myFile.getAbsolutePath()+ " -s ActivityManager:V";
Runtime.getRuntime().exec(cmd);
Logs.this.finish();
}
catch (Exception e)
{
flag=1;
error=e.getMessage();
}
I used this in a previous application for recording any application activity and make a textfile and save it to the SD card, but the contents weren't exactly what I was looking for. Is the solution im looking for something along these lines?
Here, check for the link for reference.
In here you create a class say ExceptionHandler that implements java.lang.Thread.UncaughtExceptionHandler..
Inside this class you will do your life saving stuff like creating stacktrace and gettin ready to upload error report etc....
Now comes the important part i.e. How to catch that exception.
Though it is very simple. Copy following line of code in your each Activity just after the call of super method in your overriden onCreate method.
Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler(this));
Your Activity may look something like this…
public class ForceClose extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler(this));
setContentView(R.layout.main);
}
}
Hope this helps...
You need to look up on Exception Handling. That is when your application crashes or any other app level errors occur, the code in the exception block executes. So in that place, log that error in a text-file and which solves your "log trace" issue.
Refer the link for beautiful examples.
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