diff --git a/README.md b/README.md
index 27dc08d..23d099b 100644
--- a/README.md
+++ b/README.md
@@ -56,33 +56,40 @@ CustomActivityOnCrash.setLaunchErrorActivityWhenInBackground(boolean);
```
This method defines if the error activity should be launched when the app crashes while on background.
By default, this is true. On API<14, it's always true since there is no way to detect if the app is in foreground.
-If you set it to false, a crash while in background won't launch the error activity nor the system dialog, so it will be a silent crash.
-The default is true.
+If you set it to `false`, a crash while in background won't launch the error activity nor the system dialog, so it will be a silent crash.
+The default is `true`.
```java
CustomActivityOnCrash.setShowErrorDetails(boolean);
```
This method defines if the error activity must show a button with error details.
-If you set it to false, the button on the default error activity will disappear, thus disabling the user from seeing the stack trace.
-The default is true.
+If you set it to `false`, the button on the default error activity will disappear, thus disabling the user from seeing the stack trace.
+The default is `true`.
+
+```java
+CustomActivityOnCrash.setDefaultErrorActivityDrawable(int);
+```
+This method allows changing the default upside-down bug image with an image of your choice.
+You may pass a resource id for a drawable or a mipmap.
+The default is `R.drawable.customactivityoncrash_error_image`.
```java
CustomActivityOnCrash.setEnableAppRestart(boolean);
```
This method defines if the error activity must show a "Restart app" button or a "Close app" button.
-If you set it to false, the button on the default error activity will close the app instead of restarting.
-Warning! If you set it to true, there is the possibility of it still displaying the "Close app" button,
+If you set it to `false`, the button on the default error activity will close the app instead of restarting.
+Warning! If you set it to `true`, there is the possibility of it still displaying the "Close app" button,
if no restart activity is specified or found!
-The default is true.
+The default is `true`.
```java
CustomActivityOnCrash.setRestartActivityClass(Class extends Activity>);
```
This method sets the activity that must be launched by the error activity when the user presses the button to restart the app.
If you don't set it (or set it to null), the library will use the first activity on your manifest that has an intent-filter with action
-cat.ereza.customactivityoncrash.RESTART, and if there is none, the default launchable activity on your app.
+`cat.ereza.customactivityoncrash.RESTART`, and if there is none, the default launchable activity on your app.
If no launchable activity can be found and you didn't specify any, the "restart app" button will become a "close app" button,
-even if setEnableAppRestart is set to true.
+even if `setEnableAppRestart` is set to `true`.
As noted, you can also use the following intent-filter to specify the restart activity:
```xml
@@ -98,7 +105,7 @@ CustomActivityOnCrash.setErrorActivityClass(Class extends Activity>);
This method allows you to set a custom error activity to be launched, instead of the default one.
Use it if you need further customization that is not just strings, colors or themes (see below).
If you don't set it (or set it to null), the library will use first activity on your manifest that has an intent-filter with action
-cat.ereza.customactivityoncrash.ERROR, and if there is none, a default error activity from the library.
+`cat.ereza.customactivityoncrash.ERROR`, and if there is none, a default error activity from the library.
If you use this, the activity **must** be declared in your `AndroidManifest.xml`, with `process` set to `:error_activity`.
Example:
@@ -128,6 +135,7 @@ You can override the default error activity theme by defining a theme in your ap
*Image:*
By default, an image of a bug is displayed. You can change it to any image by creating a `customactivityoncrash_error_image` drawable on all density buckets (mdpi, hdpi, xhdpi, xxhdpi and xxxhdpi).
+You can also use the provided `CustomActivityOnCrash.setDefaultErrorActivityDrawable(int)` method.
*Strings:*
@@ -140,6 +148,9 @@ You can provide new strings and translations for the default error activity stri
Error details
Error details
Close
+ Copy to clipboard
+ Copied to clipboard
+ Error information
```
*There is a `sample` project module with examples of these overrides. If in doubt, check the code in that module.*
@@ -161,13 +172,13 @@ Returns several error details including the stack trace that caused the error, a
```java
CustomActivityOnCrash.getRestartActivityClassFromIntent(getIntent());
```
-Returns the class of the activity you have to launch to restart the app, or null if not set.
+Returns the class of the activity you have to launch to restart the app, or `null` if not set.
```java
CustomActivityOnCrash.restartApplicationWithIntent(activity, intent);
```
Kills the current process and restarts the app again with an `startActivity()` to the passed intent.
-You **MUST** call this to restart the app, or you will end up having several Application class instances and experience multiprocess issues in API<17.
+You **MUST** call this to restart the app, or you will end up having several `Application` class instances and experience multiprocess issues in API<17.
```java
CustomActivityOnCrash.closeApplication(activity);
diff --git a/library/src/main/java/cat/ereza/customactivityoncrash/CustomActivityOnCrash.java b/library/src/main/java/cat/ereza/customactivityoncrash/CustomActivityOnCrash.java
index accc82e..1521eb3 100644
--- a/library/src/main/java/cat/ereza/customactivityoncrash/CustomActivityOnCrash.java
+++ b/library/src/main/java/cat/ereza/customactivityoncrash/CustomActivityOnCrash.java
@@ -50,6 +50,7 @@ public final class CustomActivityOnCrash {
private static final String EXTRA_RESTART_ACTIVITY_CLASS = "cat.ereza.customactivityoncrash.EXTRA_RESTART_ACTIVITY_CLASS";
private static final String EXTRA_SHOW_ERROR_DETAILS = "cat.ereza.customactivityoncrash.EXTRA_SHOW_ERROR_DETAILS";
private static final String EXTRA_STACK_TRACE = "cat.ereza.customactivityoncrash.EXTRA_STACK_TRACE";
+ private static final String EXTRA_IMAGE_DRAWABLE_ID = "cat.ereza.customactivityoncrash.EXTRA_IMAGE_DRAWABLE_ID";
//General constants
private final static String TAG = "CustomActivityOnCrash";
@@ -68,6 +69,7 @@ public final class CustomActivityOnCrash {
private static boolean launchErrorActivityWhenInBackground = true;
private static boolean showErrorDetails = true;
private static boolean enableAppRestart = true;
+ private static int defaultErrorActivityDrawableId = R.drawable.customactivityoncrash_error_image;
private static Class extends Activity> errorActivityClass = null;
private static Class extends Activity> restartActivityClass = null;
@@ -138,6 +140,7 @@ public void uncaughtException(Thread thread, final Throwable throwable) {
intent.putExtra(EXTRA_STACK_TRACE, stackTraceString);
intent.putExtra(EXTRA_RESTART_ACTIVITY_CLASS, restartActivityClass);
intent.putExtra(EXTRA_SHOW_ERROR_DETAILS, showErrorDetails);
+ intent.putExtra(EXTRA_IMAGE_DRAWABLE_ID, defaultErrorActivityDrawableId);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
application.startActivity(intent);
}
@@ -222,6 +225,16 @@ public static boolean isShowErrorDetailsFromIntent(Intent intent) {
return intent.getBooleanExtra(CustomActivityOnCrash.EXTRA_SHOW_ERROR_DETAILS, true);
}
+ /**
+ * Given an Intent, returns the drawable id of the image to show on the default error activity.
+ *
+ * @param intent The Intent. Must not be null.
+ * @return The id of the drawable to use.
+ */
+ public static int getDefaultErrorActivityDrawableIdFromIntent(Intent intent) {
+ return intent.getIntExtra(CustomActivityOnCrash.EXTRA_IMAGE_DRAWABLE_ID, R.drawable.customactivityoncrash_error_image);
+ }
+
/**
* Given an Intent, returns the stack trace extra from it.
*
@@ -347,6 +360,24 @@ public static void setShowErrorDetails(boolean showErrorDetails) {
CustomActivityOnCrash.showErrorDetails = showErrorDetails;
}
+ /**
+ * Returns the default error activity drawable identifier.
+ *
+ * @return the default error activity drawable identifier
+ */
+ public static int getDefaultErrorActivityDrawable() {
+ return defaultErrorActivityDrawableId;
+ }
+
+ /**
+ * Defines which drawable to use in the default error activity image.
+ * Set this if you want to use an image other than the default one.
+ * The default is R.drawable.customactivityoncrash_error_image (a cute upside-down bug).
+ */
+ public static void setDefaultErrorActivityDrawable(int defaultErrorActivityDrawableId) {
+ CustomActivityOnCrash.defaultErrorActivityDrawableId = defaultErrorActivityDrawableId;
+ }
+
/**
* Returns if the error activity should show a restart button.
* Note that even if restart is enabled, a valid restart activity could not be found.
diff --git a/library/src/main/java/cat/ereza/customactivityoncrash/activity/DefaultErrorActivity.java b/library/src/main/java/cat/ereza/customactivityoncrash/activity/DefaultErrorActivity.java
index 0a68cf3..0218cea 100644
--- a/library/src/main/java/cat/ereza/customactivityoncrash/activity/DefaultErrorActivity.java
+++ b/library/src/main/java/cat/ereza/customactivityoncrash/activity/DefaultErrorActivity.java
@@ -16,7 +16,6 @@
package cat.ereza.customactivityoncrash.activity;
-import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.ClipData;
@@ -28,9 +27,10 @@
import android.util.TypedValue;
import android.view.View;
import android.widget.Button;
+import android.widget.ImageView;
import android.widget.TextView;
-
import android.widget.Toast;
+
import cat.ereza.customactivityoncrash.CustomActivityOnCrash;
import cat.ereza.customactivityoncrash.R;
@@ -82,12 +82,13 @@ public void onClick(View v) {
.setMessage(CustomActivityOnCrash.getAllErrorDetailsFromIntent(DefaultErrorActivity.this, getIntent()))
.setPositiveButton(R.string.customactivityoncrash_error_activity_error_details_close, null)
.setNeutralButton(R.string.customactivityoncrash_error_activity_error_details_copy,
- new DialogInterface.OnClickListener() {
- @Override public void onClick(DialogInterface dialog, int which) {
- copyErrorToClipboard();
- Toast.makeText(DefaultErrorActivity.this, R.string.customactivityoncrash_error_activity_error_details_copied, Toast.LENGTH_SHORT).show();
- }
- })
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ copyErrorToClipboard();
+ Toast.makeText(DefaultErrorActivity.this, R.string.customactivityoncrash_error_activity_error_details_copied, Toast.LENGTH_SHORT).show();
+ }
+ })
.show();
TextView textView = (TextView) dialog.findViewById(android.R.id.message);
textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimension(R.dimen.customactivityoncrash_error_activity_error_details_text_size));
@@ -96,20 +97,29 @@ public void onClick(View v) {
} else {
moreInfoButton.setVisibility(View.GONE);
}
+
+ int defaultErrorActivityDrawableId = CustomActivityOnCrash.getDefaultErrorActivityDrawableIdFromIntent(getIntent());
+ ImageView errorImageView = ((ImageView) findViewById(R.id.customactivityoncrash_error_activity_image));
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+ errorImageView.setImageDrawable(getResources().getDrawable(defaultErrorActivityDrawableId, getTheme()));
+ } else {
+ //noinspection deprecation
+ errorImageView.setImageDrawable(getResources().getDrawable(defaultErrorActivityDrawableId));
+ }
}
- @SuppressLint("NewApi")
private void copyErrorToClipboard() {
String errorInformation =
- CustomActivityOnCrash.getAllErrorDetailsFromIntent(DefaultErrorActivity.this, getIntent());
+ CustomActivityOnCrash.getAllErrorDetailsFromIntent(DefaultErrorActivity.this, getIntent());
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
- android.text.ClipboardManager clipboard = (android.text.ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
- clipboard.setText(errorInformation);
- } else {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
- ClipData clip = ClipData.newPlainText("Error information", errorInformation);
+ ClipData clip = ClipData.newPlainText(getString(R.string.customactivityoncrash_error_activity_error_details_clipboard_label), errorInformation);
clipboard.setPrimaryClip(clip);
+ } else {
+ //noinspection deprecation
+ android.text.ClipboardManager clipboard = (android.text.ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
+ clipboard.setText(errorInformation);
}
}
}
diff --git a/library/src/main/res/layout/customactivityoncrash_default_error_activity.xml b/library/src/main/res/layout/customactivityoncrash_default_error_activity.xml
index 8110136..61eeb53 100644
--- a/library/src/main/res/layout/customactivityoncrash_default_error_activity.xml
+++ b/library/src/main/res/layout/customactivityoncrash_default_error_activity.xml
@@ -36,6 +36,7 @@
android:paddingTop="@dimen/customactivityoncrash_activity_vertical_margin">
Close
Copy to clipboard
Copied to clipboard
+ Error information
diff --git a/sample/src/main/java/cat/ereza/sample/customactivityoncrash/SampleCrashingApplication.java b/sample/src/main/java/cat/ereza/sample/customactivityoncrash/SampleCrashingApplication.java
index b69a7bc..aa91059 100644
--- a/sample/src/main/java/cat/ereza/sample/customactivityoncrash/SampleCrashingApplication.java
+++ b/sample/src/main/java/cat/ereza/sample/customactivityoncrash/SampleCrashingApplication.java
@@ -46,6 +46,10 @@ public void onCreate() {
//restart activity is found!
// CustomActivityOnCrash.setEnableAppRestart(false);
+ //This shows a different image on the error activity, instead of the default upside-down bug.
+ //You may use a drawable or a mipmap.
+// CustomActivityOnCrash.setDefaultErrorActivityDrawable(R.mipmap.ic_launcher);
+
//This sets a custom error activity class instead of the default one.
//If you set this, this will be used. However, you can also set it with an intent-filter:
//