Search code examples
androidcrashofflineacra

How to manually have ACRA send pending reports (offline use)


We're in this situation where our clients use our mobile application offline 95% of the time. At the end of their work day, when they get back to the office, they synchronize all data with our servers while they have network connectivity.

We have ACRA set up with the AcraHttpSender plugin to attempt sending us the crash reports directly, however this usually fails because they're using the application offline and ACRA stores the reports instead.

From what I understand the pending reports will only be sent by ACRA when the application is restarted, through ACRA.init. The problem is the users have no reason to restart the application at the end of their work day (while they have network connectivity). I have to stress that the users are complete tech illiterates, our clients made that clear to us.

So, we would really need to be able to tell ACRA to send us any pending crash reports it has during the short time network connectivity is available. Without user interaction of any kind. I was thinking maybe in the onCreate function of our main activity.

However I've been looking at documentation and other people asking the same question for a while and haven't found anything obvious. Is this possible?

EDIT: This is the current working code with the suggestion made by @F43nd1r and @CommonsWare. It wasn't working for me with 5.4.0, but with 5.5.1 it is.

Gradle

def acraVersion = '5.5.1'
implementation "ch.acra:acra-core-ktx:$acraVersion"
implementation "ch.acra:acra-http:$acraVersion"
implementation "ch.acra:acra-advanced-scheduler:$acraVersion"
implementation "ch.acra:acra-toast:$acraVersion"

Initialization

    initAcra {
        setBuildConfigClass(BuildConfig::class.java)
        setReportFormat(StringFormat.JSON)
        plugin<ToastConfigurationBuilder> {
            setResText(R.string.acra_crash_text)
            setLength(Toast.LENGTH_LONG)
            setEnabled(true)
        }
        plugin<HttpSenderConfigurationBuilder> {
            setUri("${BuildConfig.protocol}://${BuildConfig.host}/${BuildConfig.codemrc}/acra")
            setHttpMethod(HttpSender.Method.POST)
            setBasicAuthLogin("acra")
            setBasicAuthPassword("******")
            setEnabled(true)
        }
        plugin<SchedulerConfigurationBuilder> {
            setRequiresNetworkType(JobInfo.NETWORK_TYPE_ANY)
            setRestartAfterCrash(true)
            setResReportSendSuccessToast(R.string.acra_report_sent_text)
            setEnabled(true)
        }
    }

    // Turn this on to obtain more messages in the log to debug ACRA
    ACRA.DEV_LOGGING = BuildConfig.DEBUG

Solution

  • As @CommonsWare stated in the comments, AdvancedSenderScheduler is the way to go.

    Example usage:

    implementation "ch.acra:acra-advanced-scheduler:5.5.1"
    
    @AcraScheduler(requiresNetworkType = JobInfo.NETWORK_TYPE_UNMETERED,
                   requiresBatteryNotLow = true)
    

    In case you're not satisfied with AdvancedSenderScheduler options, you could also register your own SenderScheduler, but that should rarely be necessary.