I'm implementing ACRA in my Android App. I would like to be have it's interaction mode be silent by default, but if I see that a new version of my App is available, "Toast" the user upon crash with a message to update their copy of the App.
However it seems that ACRA interaction mode must be hard coded and loaded once upon init of application. Any way to set the mode at that point not via a hard coded setting? E.g. I'm looking to control the "mode = " setting which is copied below.
#ReportsCrashes(formKey = "xxxxxxxxxxxxxxxx",
mode = ReportingInteractionMode.TOAST,
resToastText = R.string.crash_toast_text)
public class MyApplication extends Application ...
I see that ACRA Issue 85 has added setters for resources for Toast parameters, but does it also have ability to configure interaction mode?
Maybe this? I didn't try but seems useful (at point of start)
http://www.java2s.com/Open-Source/Android/App/acra/org/acra/ErrorReporter.java.htm
Related
i am using ACRA for error reporting and everything seems to be fine.
i want to send report of handled exceptions as well so i am using
ACRA.getErrorReporter().handleException(e);
but don't want the Toast to appear on the handled exceptions. but want toast on unhandled exceptions! so is there any way to specify this condition?
EDIT
#ReportsCrashes(
httpMethod = HttpSender.Method.POST,
reportType= HttpSender.Type.JSON,
formUri = MFRestConstants.CREATE_ACRA_REPORT,
mode = ReportingInteractionMode.TOAST,
resToastText = R.string.msg_toast_text,
additionalSharedPreferences={"MutterflyAppPref"}
)
There is a method called handleSilentException.
Usage: ACRA.getErrorReporter().handleSilentException(e);
Although I haven't used ACRA before but it is obvious that your mode is set to
mode = ReportingInteractionMode.TOAST
This should display a Toast shouldn't it?
You should simply remove that line because you don't want to notify the user I guess !!
Thanks to Proguard's optimization features I am now able to do as much debug-logging as I which in my code - for production I simply let it strip all this unnecessary code.
That is fine and works (with the latest Proguard version).
But: before I went this way, I had my final static boolean DEBUG constant that "guarded" all my Log.d/Log.v calls. To ensure I did not forget to disable that for signed production apk's, I just had an easily visible add on in my UI main activity that in some corner put an ugly text "DEBUG IS ON".
So, when producing my final apk, all I had to do is install it once - in case I forgot to switch debug mode off, I was reminded by that.
Now, with Proguard doing the work of removing debug-log-calls: how could I DETECT that in my app and control a UI element that states "DEBUG IS ON"?
Any idea?
My first attempt was to try this:
boolean loggingEnabled = false;
Log.d(TAG, (loggingEnabled = true) ? "Logging test" : "");
And I hoped that Proguard would also remove the assignment loggingEnabled=true- but I underestimated Proguard. It removes the call to Log.d, but still does the assignment... :)
You can do a few things:
Check the mapping.txt in proguard's output folder: grep -E '(android/util/|de/ub0r/android/logg0r/)Log.[dv]' */build/proguard/release/dump.txt
Run the app and check if any d/v log is printed.
Decompilte the app and look at the source code for calls to Log.d() and Log.v().
I build a simple wrapper library to make it a little bit more handy:
https://github.com/felixb/ub0rlogg0r
--- EDIT ---
To Check if your logs got stripped, do the following:
Fork ub0rlogg0r.
Add a public static boolean sHasDebugCalls = false; to Log.
Add sHasDebugCalls = true to all the Log.d() and Log.v() methods.
Place a Log.d(TAG, "has debug logs") somewhere in the very beginning of your app.
When creating your UI, test for Log.sHasDebugCalls to decide visibility of the DEBUG reminder.
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 want to check if my app is running on a background mode.
The problem is that i have many activities(list activities, map activities etc.). Initially I have tried in the life cycle's resume and pause(or the onUserLeaveHint) methods to set a static boolean as true or false and work with this way. But this obviously can't work because when I move from one activity to another, the previous one get paused.
Also, I've read here on stackoverflow that the getRunningTasks() should be used only for debugging purposes. I did a huge research but I can't find a solution. All I want to do is to be able to detect if a the app is running on a background. Can anyone propose me a way, or express any thought on how can I do that?
You can try the same mechanism (a boolean attribute) but on application side rather than activity side. Create a class which extends Application, declare it in the manifest file under <application android:name=YourClassApp>.
EDIT: I assume you know that activities aren't intended for background processing, if not you should take a look at the Services.
I don't know if this will help but you can use
getApplicaton().registerActivityLifecycleCallbacks(yourClass);
To get a birds eye view of how your activities are displayed in the FG. (For older s/w you can use this)
If your Application has a Service you could have a static get/set which accesses a static variable. Do not do this in Activities though, it causes mem leaks.
But realistically speaking there is no tidy way of tracking if your application is running or not.
I had the same problemen when overwriting the Firebase push messaging default behavior (show notifications only when in the background) I checked how Firebase did this by looking in the .class file com.google.firebase.messaging.zzb:53 (firebase-messaging:19.0.1) which appears to us getRunningAppProcesses. Mind you FireBase is created by Google them self. So I'm assuming it's pretty save to use. Cleaned up version:
List<ActivityManager.RunningAppProcessInfo> runningApps;
boolean isInForeground =false;
if ((runningApps = ((ActivityManager)this.getApplication().getSystemService(Context.ACTIVITY_SERVICE)).getRunningAppProcesses()) != null) {
Iterator runningApp = runningApps.iterator();
int myPid = Process.myPid();
while(runningApp.hasNext()) {
ActivityManager.RunningAppProcessInfo processInfo;
if ((processInfo = (ActivityManager.RunningAppProcessInfo)runningApp.next()).pid == myPid) {
isInForeground = processInfo.importance == 100;
break;
}
}
}
I'm dealing with a random problem which related to camera usage. Before I call camera intent - I generate UUID to store file with this name. I store this UUID in private variable like so:
private String requestedFileName;
When camera done - I'm processing this file, looks something like this:
public void onPictureTaken(int index)
{
//First of all - remember picture in database for reference.
FileData.InsertFile(mContext, UUID.fromString(requestedFileName));
//Reduce taken picture if needed, otherwise let it be original.
if (Preferences.getImageSize(mContext) > 0)
{
Imaging.scaleImageFile(mContext, requestedFileName, Preferences.getImageSize(mContext));
}
I see users report issue exception that boils down to requestedFileName == null when onPictureTaken called
Caused by: java.lang.NullPointerException
at java.util.UUID.fromString(UUID.java:210)
at com.idatt.views.FourImagesView.onPictureTaken(FourImagesView.java:151)
at com.idatt.views.TrailerUnitView.onPictureTaken(TrailerUnitView.java:233)
Everything works good on my phone (Nexus S) and in emulator. But users report this exception and I'm not sure why this is happening..
I've seen this happen on the Nexus phones, and some others. If you use DDMS to watch what is going on, I bet you'll see that your process is actually being terminated and then restarted. Thus your local state is being lost. You need to persist it, since Android can basically kill your process and restart it whenever it wants if you switch to a new task (and most of the camera capture intents set the NEWTASK flag).
If your class is an Activity you can use onSaveInstanceState() to store your filename, then read it back out of the Bundle you get in onCreate().
If you are not an Activity you can use the SharedPreferences store as a temporary place to save the filename:
private static void saveTempFileName(Context context, String filename) {
SharedPreferences settings = context.getSharedPreferences("whatever", 0);
SharedPreferences.Editor editor = settings.edit();
editor.putString("com.yourstuff.whatever", filename);
editor.commit();
}
As #jeffamaphone noted you are probably having issues with app configuration changes. Application configuration change happens when something happens that affects the runtime environment of your app. Most notably this are: orientation change or keyboard hide/show.
Try this: start your app, invoke the Camera app (via your app action), change orientation, return to your app (via appropriate action). Does this sequence produce the error? Then you have issues with configuration change - when orientation changes usually (depending on your app settings) Android system restarts (kills and creates new instance) your Activity, which probably creates all new Views (without UUID set).
See handling configuration changes.