I'm using the android crittercism library and trying to send a report when I catched an error level exception.
But I can't find the documentation on how to do that. Is this even possible? If so, how?
They temporarily moved the feature into beta. If you e-mail support they'll enable your account for handled exceptions. Below is the sample Android code:
try
{
throw new Exception("Exception Reason");
}
catch (Exception exception)
{
Crittercism.logHandledException(exception);
}
Just in case you need it, here is sample code on iOS:
#try {
[NSException raise:NSInvalidArgumentException
format:#"Foo must not be nil"];
} #catch (NSException *exception) {
// Pass it on to us!
[Crittercism logHandledException:exception]
}
I'm the co-founder and CTO of Crittercism. If you send me an awesome email, I can enable it for your account. I'm rob[at] :)
Crittercism.logHandledException(new Throwable("test"));
You don't actually have to throw the Exception (or Throwable, in this case).
It will appear under "Handled Exceptions" on Crittercism website.
Related
I have a question regarding the Koin handling exception.
In a module where I defined EncryptedSharedPreferences.create(), sometimes causing an exception, which results in a crash in the user's device. I see in the crashlytic report that the crash already happens over 200 times. More specific exception is below.
Caused by java.security.UnrecoverableKeyException: Failed to obtain information about key
...
Caused by android.security.KeyStoreException: -49
Apparently, this issue is already reported, yet there's no valid answer to handle or solving it. Because I'm using Koin to define the EncryptedSharedPreferences, I thought it's better to handle it inside single{} function. Put a try catch that will catch the exception. But when I try to throw an Exception inside try, it didn't catch the Exception, it's just crash, not what I expecting. The code looks like below
single(named(ENCRYPTED_SHARED_PREF)) {
val context = androidApplication().applicationContext
try {
val masterKey =
MasterKey.Builder(context, MasterKey.DEFAULT_MASTER_KEY_ALIAS)
.setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
.build()
EncryptedSharedPreferences.create(
context,
SP_ENCRYPTED_KEY,
masterKey,
EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
)
throwError()
} catch (e: Exception) {
Timber.d("[SHARED PREF] Terjadi exception")
when (e) {
is KeyStoreException -> {
Toast.makeText(context, "Terjadi exception", Toast.LENGTH_SHORT).show()
}
}
//Update missing link below
androidApplication().getSharedPreferences(SP_KEY, Context.MODE_PRIVATE)
}
}
...
#Throws(KeyStoreException::class)
fun throwError(): Nothing {
throw KeyStoreException("Terjadi exception")
}
Now for the question, is there's a way to handle this kind of Exception inside Koin single or not? I had try to search for the documentation and google it, seems a dead end to me.
Other useful information:
EncryptedSharedPreferences version : androidx.security:security-crypto:1.1.0-alpha03
Issue tracker for EncryptedSharedPreferences I faced : https://issuetracker.google.com/u/1/issues/167977579
The crash or exception not related to Koin issue, rather it's on EncryptedSharedPreferences
Koin version : org.koin:koin-android-viewmodel:2.1.6
UPDATE SOLVE
Took me a while to realize that the catch block needs to return something such as a value or another object, let say normally shared preference. Nothing wrong with the code thought after in-depth research. Thanks all, I also update the code in my explanation above.
if your try - catch is not working and your app crashes , it means that the things inside the try block are in another thread . check this
i had the same problem , but not inside koin init . i fixed by using android coroutine -> i can catch the exception now
you can also check for async variables inside koin here
I am using the Amazon AWS SDK to download images from S3. Occasionally, when an image is not found an exception "AmazonS3Exception: Status Code: 404" is thrown. However, this seems like an exception which should not crash the app. How can I handle this exception so that it does not crash the app? Apologies, Im a noob to Java & Android.
To follow up on type-a1pha's answer:
If you want to handle an exception gracefully, you would use a try-catch statement. It works something like this:
try {
// Here you put the code that may throw an exception
} catch (AmazonS3Exception e) {
// Looks like we errored out, log the exception and
// tell the user that we 404'd
Log.e(TAG, "Error fetching file from Amazon S3", e);
Toast.makeText(context, "Error 404 while fetching file: file not found", Toast.LENGTH_SHORT).show();
// Insert any other code you need here to recover from the error
} finally {
// Note that the finally part is optional but useful if you want
// to do something after the try-catch statement is finished
// for example, if you were using an inputStream:
inputStream.close();
}
try{
//code throwing exception
} catch (AmazonS3Exception) {}
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
In my app I want to catch all types of exceptions and send reports by e-mail. For that I'm using global try catch block. But now I need to recognize exception by type. How can I do it?
try{
...
}
catch (Exception e){
//Here I need to recognize exception by type
send(Error);
}
Why you don't simple send the whole stacktrace?
send(e.getStackTrace())
It not only contains the Exception type but also where (file, class, line) it occurred.
Additionally, you can also simply use the toString() method.
See the java doc for further information
Instead of rolling your own error logging and reporting mechninism I strongly recommend you use ACRA Its free, open source, and supports sending error logs to email. I have used it for quite some time and it is very good.
This will give you all sorts of information such as phone make, model, resolution, free memory, as well as a full stack trace of the error. Its by far the easiest way to get quality error reporting into an Android app.
The best part is it takes all of about 5 minutes to get setup and integrated.
e.getClass() // will give you Class object
e.getClass().getName() // will give you class name
However if you know the class names already you can use
if(e instanceof A)
{
// some processing
}
else if(e instanceof B)
{
//some processing
}
else
{
//
}
on Android phones, under Call -> Additional settings -> Caller ID
it is possible to hide your caller ID. I want to do that programatically from my code, but was not able to find a way to do that.
I searched through
android.provider
android.telephony
for 2.1 release and was not able to find it.
Has anybody successfully solved this issue?
Thanks in advance. Best regards.
Here I will describe two approaches I tried.
1.) It is possible to display Additional Call Settings screen from your application. Although it looks like it is part of the Settings application, that is not true. This Activity is part of the Native Phone Application, and it may be approached with the following intent:
Intent additionalCallSettingsIntent = new Intent("android.intent.action.MAIN");
ComponentName distantActivity = new ComponentName("com.android.phone", "com.android.phone.GsmUmtsAdditionalCallOptions");
additionalCallSettingsIntent.setComponent(distantActivity);
startActivity(additionalCallSettingsIntent);
Then user has to manually press on the CallerID preference and gets radio button with 3 options.
This was not actually what I wanted to achieve when I asked this question. I wanted to avoid step where user has to select any further options.
2.) When approach described under 1.) is executed in the Native Phone Application, function setOutgoingCallerIdDisplay() from com.android.internal.telephony.Phone has been used.
This was the basis for the next approach: use Java Reflection on this class and try to invoke the function with appropriate parameters:
try
{
Class <?> phoneFactoryClass = Class.forName("com.android.internal.telephony.PhoneFactory");
try
{
Method getDefaultPhoneMethod = phoneFactoryClass.getDeclaredMethod("getDefaultPhone");
Method makeDefaultPhoneMethod = phoneFactoryClass.getMethod("makeDefaultPhone" , Context.class);
try
{
makeDefaultPhoneMethod.invoke(null, this);
Object defaultPhone = getDefaultPhoneMethod.invoke(null);
Class <?> phoneInterface = Class.forName("com.android.internal.telephony.Phone");
Method getPhoneServiceMethod = phoneInterface.getMethod("setOutgoingCallerIdDisplay", int.class, Message.class);
getPhoneServiceMethod.invoke(defaultPhone, 1, null);
}
catch (InvocationTargetException ex)
{
ex.printStackTrace();
}
catch (IllegalAccessException ex)
{
ex.printStackTrace();
}
}
catch (NoSuchMethodException ex)
{
ex.printStackTrace();
}
}
catch (ClassNotFoundException ex)
{
ex.printStackTrace();
}
Firstly I tried just to use getDefaultPhone(), but I get RuntimeException
"PhoneFactory.getDefaultPhone must be called from Looper thread"
Obviously, issue lies in the fact that I tried to call this method from the Message Loop that was not the Native Phone App one.
Tried to avoid this by making own default phone, but this was a security violation:
ERROR/AndroidRuntime(2338): java.lang.SecurityException: Permission Denial: not allowed to send broadcast android.provider.Telephony.SPN_STRINGS_UPDATED from pid=2338, uid=10048
The only way to overcome (both of) this would be to sign your app with the same key as the core systems app, as described under
Run secure API calls as root, android
I'm not sure if this is a global feature, but Australian phones can hide their number by prefixing the caller's number with #31# or 1831. This may not be the perfect solution, but a prefix like this could possibly work for your requirements during coding.