7

I have an android application and i want to know on the startup of this application whether my application crashed previously or not. This crash may be crash enforced by OS on app for saving memory or any other reason. It may not be caught in UnhandledExceptionHandler. What i have handled so far is given below and it is not caching those native os related and memory enforced cases

UncaughtExceptionHandler handler = new UncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(handler);

EDIT:

Please don't suggest 3rd party libraries.

CopsOnRoad
  • 237,138
  • 77
  • 654
  • 440
Syed Wajahat Ali
  • 541
  • 1
  • 7
  • 25
  • Take a look at [this question](http://stackoverflow.com/questions/601503/how-do-i-obtain-crash-data-from-my-android-application), it sounds like you want something like this. – G_V Jan 12 '15 at 10:52
  • @G_V I have looked into it but it is showing me external libraries plus these reports also wont catch OS related crashes like memory crash etc – Syed Wajahat Ali Jan 12 '15 at 10:53
  • You can't ask your application to detect a system crash that happened before because it does not even noticed it. It just got killed by the OS/kernel. What you ask is not possible AFAIK, at least not to that extent. – shkschneider Jan 12 '15 at 11:09

3 Answers3

2

This would be happen via SharedPreferences, first of all when you just enter your app in the MainActivity create a boolean variable called crash and save it to your SharedPreferences with a value of false, then when catching a crash, just resave this variable with the value true and this will automatically override the crash value stored before.

To save the value:

private void savePreferences(String key, String value) {
    SharedPreferences sharedPreferences = PreferenceManager
            .getDefaultSharedPreferences(this);
    Editor editor = sharedPreferences.edit();
    editor.putBoolean("crash", false);
    editor.commit();
}

To load the saved value:

private void loadSavedPreferences() {
    SharedPreferences sharedPreferences = PreferenceManager
            .getDefaultSharedPreferences(this);
    boolean crash = sharedPreferences.getBoolean("crash", false);
    if(crash){
        // then your app crashed the last time
    }else{
        // then your app worked perfectly the last time
    }
}

So, in your crash handler class, just save the value to true:

p.s. this must run for all unHandled Exceptions whatever from the app of from the OS.

public class CrashHandler extends Application{

    public static Context context;

    public void onCreate(){
        super.onCreate();

        CrashHandler.context = getApplicationContext();
        // Setup handler for uncaught exceptions.
        Thread.setDefaultUncaughtExceptionHandler (new Thread.UncaughtExceptionHandler()
        {
          @Override
          public void uncaughtException (Thread thread, Throwable e)
          {
            handleUncaughtException (thread, e);
          }
        });

    }

    public void handleUncaughtException (Thread thread, Throwable e)
    {
      e.printStackTrace(); // not all Android versions will print the stack trace automatically

      SharedPreferences sharedPreferences = PreferenceManager
                .getDefaultSharedPreferences(context);
        Editor editor = sharedPreferences.edit();
        editor.putBoolean("crash", true);
        editor.commit();

    }

}
Muhammed Refaat
  • 8,914
  • 14
  • 83
  • 118
1

I have found a hack and it worked for me. One can check if its app was crashed if one knows whether user left the app or shut down the system or did any such thing or the app itself got closed. If the app itself got closed it means that it was crashed otherwise it wasn't (in cases such as user closing app or shutting down system).

With help of shared preferences one can store and get a variable which will tell if app was crashed or not the code is given below

public class Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    boolean appcrashed=false;
    super.onCreate(savedInstanceState);
    boolean didUserLeft=loadSavedPreferences();
    appcrashed=!didUserLeft;
    if(appcrashed)
        Toast.makeText(this, "App Crashed!", Toast.LENGTH_LONG).show();
    else
        Toast.makeText(this, "App OK!", Toast.LENGTH_LONG).show();
    savePreferences(false);

    UnhandledExceptionHandler handler = new UnhandledExceptionHandler();

    Thread.setDefaultUncaughtExceptionHandler(handler);

}


public boolean loadSavedPreferences() {
    SharedPreferences sharedPreferences = PreferenceManager
            .getDefaultSharedPreferences(this);
    boolean didUserLeft = sharedPreferences.getBoolean("didUserLeft", true);
    return didUserLeft;
}

public void savePreferences(boolean value) {
    SharedPreferences sharedPreferences = PreferenceManager
            .getDefaultSharedPreferences(this);
    Editor editor = sharedPreferences.edit();
    editor.putBoolean("didUserLeft", value);
    editor.commit();
}

@Override
public void onResume(){
    super.onResume();
    savePreferences(false);
}

@Override
public void onDestroy(){
    savePreferences(true);
}

@Override
public void onPause() {
    super.onPause();  // Always call the superclass method first
    savePreferences(true);
    }


@Override
public void onUserLeaveHint(){
    savePreferences(true);
}
Syed Wajahat Ali
  • 541
  • 1
  • 7
  • 25
0

1) When Android kills and restarts your app, static variables are set to null (more precisely, initially set to null and a bit later, very soon, set to their initial values; a static initializer may see null in variables that has not yet been initialized). So if some static variable is set to null whereas the data in a Bundle say the user has been doing something, there was a process restart (I assume you know what Bundle is for in onCreate(Bundle)).

2) You may have a flag in persistent storage; the flag will be, say, set to true when the application has started and set to false before it finishes normally. If that flag is true when the application starts, there was a crash. (There is still a small possibility that the app crashes after it has closed normally... But is it important for you?)

3) You may save the app's pid in persistent memory (see myPid()).

18446744073709551615
  • 16,368
  • 4
  • 94
  • 127