Just started using ACRA. When the application crashes it sends a report to my server. All is well.
But there are exceptions which I can catch and let the user keep the problem without error - like using default values. But I'd like to get an error report without bothering the user. But when I do:
ErrorReporter errorReporter = ACRA.getErrorReporter();
errorReporter.putCustomData("test", "value");
errorReporter.handleSilentException(null);
the application shuts down. I first tried throwing some error (testing purposes), I hoped sending null would stop the app from stopping - I was wrong.
Is there a way to use ACRA to send an error report without exiting the app? Just thought I had it, but
ErrorReporter errorReporter = ACRA.getErrorReporter();
errorReporter.putCustomData("test", "value");
errorReporter.handleException(null, false); // false is endApplication param, `null` seems to result in a NullPointerException
This also closes the application (without an additional Exception from ACRA):
ErrorReporter errorReporter = ACRA.getErrorReporter();
errorReporter.putCustomData("test", "value");
errorReporter.handleException(new RuntimeException("message"), false); // tried `true` also, just in case
Also closes the app
Update:
(1) LogCat shows no stack trace.
(2) While reading the error report, my eye fell on
"DUMPSYS_MEMINFO":"Permission Denial: can't dump meminfo from from pid=1416, uid=10048 without permission android.permission.DUMP\n"
Tried to add android.permission.DUMP to androidmanifest.xml, but I get Permission is only granted to system apps. Reason for exiting app? Work around? It gets all information that I need (and more)...
As it turns out, the above code is correct. The problem was in that I have overwritten the ErrorReporter:
new HttpSender(org.acra.sender.HttpSender.Method.PUT, org.acra.sender.HttpSender.Type.JSON, null) {
#Override
public void send(final Context context, final CrashReportData report) throws ReportSenderException {
super.send(context, report);
respondAsIfCrashing(); // not the real method name
}
};
The application wasn't crashing, it just appeared to do that, because of the respondAsIfCrashing method.
The warning DUMPSYS_MEMINFO":"Permission Denial: can't dump meminfo from from pid=1416, uid=10048 without permission android.permission.DUMP is, apparently, not a reason to crash... (perhaps just not writing to device?)
So using
ErrorReporter errorReporter = ACRA.getErrorReporter();
errorReporter.handleException(new RuntimeException("message"), false);
Is sufficient
Related
Currently trying to obtain profile trace logs files for a huge Android app, that we have instrumented on MyApplication class, following the documentation about instrumenting my app to get trace logs.
We are trying to dig into what happens when our app is initialized and Dagger2 creates the object graph when the app is started.
A cold startup can take a few seconds normally, the issue I have is that when I add the Debug traces, it dramatically slows down the initialization of the app, making it crash with an ANR message.
com.github.anrwatchdog.ANRError: Application Not Responding
Caused by: com.github.anrwatchdog.ANRError$$$_Thread: main (state = RUNNABLE)
I would like to know if there is a way to prevent the Android OS from crashing my app when it blocks for a long period of time, or to at least increase the ANR threshold.
Any help or tips are welcome. Thanks!
For further context, this is roughly what I am doing in my MyApplication.class:
public void onCreate() {
super.onCreate();
Debug.startMethodTracing("MyApp_onCreate()");
injectSelf();
AppInit.initApp(this);
Debug.stopMethodTracing();
}
Actually, it turns out we have our own ANRWatchDogManager which I wasn't aware of, where I can extend the limit.
public class ANRWatchDogManager implements ANRWatchDog.ANRListener {
Somewhere in that class:
public void startANRWatchDog() {
final int timeoutInterval = isDebugBuild() && isEmulator()
? ANR_INCREASED_TIMEOUT
: ANR_DEFAULT_TIMEOUT;
new ANRWatchDog(timeoutInterval).setANRListener(this).start();
}
Sometimes my application crashes while trying to open it. As the app hasn't completely started I don't get an error report. I also can't connect my application to the emulator because this behaviour is not reproducable. Sometimes it just crashes once. In other times I can try to open/reopen it as often as I want and it works perfect.
I only use the network-connection (no camera and other stuff). I don't have any services which could crash the application and I tried to reproduce my error by trying to stop the application while it loads something in the background - no success at all.
What do you think could be the reason for crashing? How can I get a log-file, stacktrace something useful for fixing this problem? I simply can't reproduce it so I never see a Logcat-Output when it occurs.
It might be a Fragment-Initializing-Problem but I can't see my mistake. This never occured before and it's just not a common mistake. It might crash only once/twice a week - but it crashes in some point in time...
I've uploaded my project on github but I don't think this is helping somehow.
My main question is: What for opportunities do I have to see what might be the reason behind these random crashes?
Root your phone and install CatLog. When it crashes, open CatLog and save the log so you can view it later.
Or try this if you want to automate it:
Create an exception handler that saves a stack trace to a file.
public class UncaughtExceptionSaver implements UncaughtExceptionHandler{
UncaughtExceptionHandler previousHandler;
Context context;
public UncaughtExceptionSaver (Context context){
this.context = context;
previousHandler= Thread.getUncaughtExceptionHandler();
}
#Override
void uncaughtException(Thread t, Throwable e){
/*Save the stacktrace from the throwable to a
file in your external directory, using context. */
previousHandler.uncaughtException(t,e);
}
}
Then in an Application subclass, call this in the onCreate method:
Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionSaver(this));
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());
Hi all,
I'm using (trying at the moment) ACRA for bug-reporting. Scenario is:
I open the app: ACRA outputs ACRA is enabled for mypackage, intializing...
I enter the Settings (where I prepared a NullpointerException)
The app freezes and Preparing crash dialog is output via a toast
The app does not close, but instead outputs the same toast again and again (all Views are gone)
When I close the app, after a few seconds (of gathering data I guess) the crash dialog opens
I have the following Annotation in front of my Application subclass:
#ReportsCrashes(formKey = "iwontshowyoumyformkey", customReportContent = {
REPORT_ID, APP_VERSION_CODE, ANDROID_VERSION, PHONE_MODEL, BRAND,
STACK_TRACE },
mode = ReportingInteractionMode.DIALOG,
resToastText = R.string.acra_toast_text,
resDialogText = R.string.acra_dialog_text,
resDialogTitle = R.string.acra_dialog_title,
resDialogCommentPrompt = R.string.acra_dialog_comment_prompt,
resDialogOkToast = R.string.acra_dialog_ok_toast,
forceCloseDialogAfterToast=true)
A notable detail is that the error occurs again and again, according to the Logcat.
This made me think that the activity is restarted all the time, and the error is in onCreate...
But the fact that the tag is ACRA made me unsure if it isnt ACRA, reoutputting the error.
Problem: The app should be crashed and closed so that the dialog can appear, but isn't.
Question: How would I go about debugging/solving this? A solution would be even better...
Thank you in advance,
Till
It's not solved, but I decided to not spend any more time on it, and abandon ACRA.
Crittercism has proven to be quite painless.
I am stuck writing some code that uses reflection that calls IConnectivityManager.startLegacyVpn
The error I get is java.lang.SecurityException: Unauthorized Caller
Looking through the android source I see this is the code hanging me up:
if (Binder.getCallingUid() != Process.SYSTEM_UID) { raise the above exception }
My question is if I root my AVD and install my app in system/app will this be sufficient to get around this error?
If so, any tips on how to do this (every time I try to move my apk to the system/app folder it says the app is not installed when I click on the app icon.
Thanks!
I have the same problem, following android 4.01 open source, i see somethings like this:
public synchronized LegacyVpnInfo getLegacyVpnInfo() {
// Only system user can call this method.
if (Binder.getCallingUid() != Process.SYSTEM_UID) {
throw new SecurityException("Unauthorized Caller");
}
return (mLegacyVpnRunner == null) ? null : mLegacyVpnRunner.getInfo();
}
Or,
// Only system user can revoke a package.
if (Binder.getCallingUid() != Process.SYSTEM_UID) {
throw new SecurityException("Unauthorized Caller");
}
Or,
public void protect(ParcelFileDescriptor socket, String interfaze) throws Exception {
PackageManager pm = mContext.getPackageManager();
ApplicationInfo app = pm.getApplicationInfo(mPackage, 0);
if (Binder.getCallingUid() != app.uid) {
throw new SecurityException("Unauthorized Caller");
}
jniProtect(socket.getFd(), interfaze);
}
However, these block of code above is belongs to com.android.server.connectivity.Vpn
(class Vpn), which is not defined in interface IConnectivityManager.
I also find in startLegacyVpnInfo() function but i can't see anything involve exception
"Unauthorized Caller", so i wonder why startLegacyVpnInfo() function throws this exception?
Any solutions for this?
I am trying to make the same calls. So far I can confirm that rooting the device and copying the apk to /system/app does not work, it does not start under the system uid.
Also, this does not work:
Field uidField = Process.class.getDeclaredField("SYSTEM_UID");
uidField.setAccessible(true);
uidField.set(null, Process.myUid());
Those calls succeed, but they don't seem to affect the SYSTEM_UID field, the field is probably optimized out at compile time.
If you include android: sharedUserId="android.uid.system" into your manifest tag (not just the manifest), this should then run the application as system. This should now let you run the code.
As for pushing to /system/app, you need to run adb root followed by adb remount. This will now let you push to /system/app.