Search in sources :

Example 1 with SharedPreferencesFactory

use of org.acra.prefs.SharedPreferencesFactory in project acra by ACRA.

the class ApplicationStartupProcessor method deleteUnsentReportsFromOldAppVersion.

/**
     * Delete any old unsent reports if this is a newer version of the app than when we last started.
     */
public void deleteUnsentReportsFromOldAppVersion() {
    final SharedPreferences prefs = new SharedPreferencesFactory(context, config).create();
    final long lastVersionNr = prefs.getInt(ACRA.PREF_LAST_VERSION_NR, 0);
    final int appVersion = getAppVersion();
    if (appVersion > lastVersionNr) {
        final BulkReportDeleter reportDeleter = new BulkReportDeleter(context);
        reportDeleter.deleteReports(true, 0);
        reportDeleter.deleteReports(false, 0);
        final SharedPreferences.Editor prefsEditor = prefs.edit();
        prefsEditor.putInt(ACRA.PREF_LAST_VERSION_NR, appVersion);
        PrefUtils.save(prefsEditor);
    }
}
Also used : BulkReportDeleter(org.acra.file.BulkReportDeleter) SharedPreferences(android.content.SharedPreferences) SharedPreferencesFactory(org.acra.prefs.SharedPreferencesFactory)

Example 2 with SharedPreferencesFactory

use of org.acra.prefs.SharedPreferencesFactory in project acra by ACRA.

the class ReportExecutor method execute.

/**
     * Try to send a report, if an error occurs stores a report file for a later attempt.
     *
     * @param reportBuilder The report builder used to assemble the report
     */
public void execute(@NonNull final ReportBuilder reportBuilder) {
    if (!enabled) {
        ACRA.log.v(LOG_TAG, "ACRA is disabled. Report not sent.");
        return;
    }
    // Prime this crash report with any extra data.
    reportPrimer.primeReport(context, reportBuilder);
    boolean sendOnlySilentReports = false;
    final ReportingInteractionMode reportingInteractionMode;
    if (!reportBuilder.isSendSilently()) {
        // No interaction mode defined in the ReportBuilder, we assume it has been set during ACRA.initACRA()
        reportingInteractionMode = config.mode();
    } else {
        reportingInteractionMode = ReportingInteractionMode.SILENT;
        // explicitly declared as silent via handleSilentException().
        if (config.mode() != ReportingInteractionMode.SILENT) {
            sendOnlySilentReports = true;
        }
    }
    final boolean shouldDisplayToast = reportingInteractionMode == ReportingInteractionMode.TOAST || (config.resToastText() != 0 && (reportingInteractionMode == ReportingInteractionMode.NOTIFICATION || reportingInteractionMode == ReportingInteractionMode.DIALOG));
    final TimeHelper sentToastTimeMillis = new TimeHelper();
    if (shouldDisplayToast) {
        new Thread() {

            /*
                 * (non-Javadoc)
                 *
                 * @see java.lang.Thread#run()
                 */
            @Override
            public void run() {
                Looper.prepare();
                ToastSender.sendToast(context, config.resToastText(), Toast.LENGTH_LONG);
                sentToastTimeMillis.setInitialTimeMillis(System.currentTimeMillis());
                Looper.loop();
            }
        }.start();
    // We will wait a few seconds at the end of the method to be sure
    // that the Toast can be read by the user.
    }
    final CrashReportData crashReportData = crashReportDataFactory.createCrashData(reportBuilder);
    // Always write the report file
    final File reportFile = getReportFileName(crashReportData);
    saveCrashReportFile(reportFile, crashReportData);
    final SharedPreferences prefs = new SharedPreferencesFactory(context, config).create();
    if (reportingInteractionMode == ReportingInteractionMode.SILENT || reportingInteractionMode == ReportingInteractionMode.TOAST || prefs.getBoolean(ACRA.PREF_ALWAYS_ACCEPT, false)) {
        // Approve and then send reports now
        startSendingReports(sendOnlySilentReports);
        if ((reportingInteractionMode == ReportingInteractionMode.SILENT) && !reportBuilder.isEndApplication()) {
            // So no need to wait around for the sender to complete.
            return;
        }
    } else if (reportingInteractionMode == ReportingInteractionMode.NOTIFICATION) {
        if (ACRA.DEV_LOGGING)
            ACRA.log.d(LOG_TAG, "Creating Notification.");
        createNotification(reportFile, reportBuilder);
    }
    final boolean showDirectDialog = (reportingInteractionMode == ReportingInteractionMode.DIALOG) && !prefs.getBoolean(ACRA.PREF_ALWAYS_ACCEPT, false);
    if (shouldDisplayToast) {
        // A toast is being displayed, we have to wait for its end before doing anything else.
        new Thread() {

            @Override
            public void run() {
                if (ACRA.DEV_LOGGING)
                    ACRA.log.d(LOG_TAG, "Waiting for " + ACRAConstants.TOAST_WAIT_DURATION + " millis from " + sentToastTimeMillis.initialTimeMillis + " currentMillis=" + System.currentTimeMillis());
                final long sleep = ACRAConstants.TOAST_WAIT_DURATION - sentToastTimeMillis.getElapsedTime();
                try {
                    // Wait a bit to let the user read the toast
                    if (sleep > 0L)
                        Thread.sleep(sleep);
                } catch (InterruptedException e1) {
                    if (ACRA.DEV_LOGGING)
                        ACRA.log.d(LOG_TAG, "Interrupted while waiting for Toast to end.", e1);
                }
                if (ACRA.DEV_LOGGING)
                    ACRA.log.d(LOG_TAG, "Finished waiting for Toast");
                dialogAndEnd(reportBuilder, reportFile, showDirectDialog);
            }
        }.start();
    } else {
        dialogAndEnd(reportBuilder, reportFile, showDirectDialog);
    }
}
Also used : ReportingInteractionMode(org.acra.ReportingInteractionMode) CrashReportData(org.acra.collector.CrashReportData) SharedPreferences(android.content.SharedPreferences) SharedPreferencesFactory(org.acra.prefs.SharedPreferencesFactory) File(java.io.File)

Example 3 with SharedPreferencesFactory

use of org.acra.prefs.SharedPreferencesFactory in project acra by ACRA.

the class ACRA method init.

/**
     * <p>
     * Initialize ACRA for a given Application. The call to this method should
     * be placed as soon as possible in the {@link Application#attachBaseContext(Context)}
     * method.
     * </p>
     *
     * @param app       Your Application class.
     * @param config    ACRAConfiguration to manually set up ACRA configuration.
     * @param checkReportsOnApplicationStart    Whether to invoke ErrorReporter.checkReportsOnApplicationStart().
     * @throws IllegalStateException if it is called more than once.
     */
public static void init(@NonNull Application app, @NonNull ACRAConfiguration config, boolean checkReportsOnApplicationStart) {
    final boolean senderServiceProcess = isACRASenderServiceProcess();
    if (senderServiceProcess) {
        if (ACRA.DEV_LOGGING)
            log.d(LOG_TAG, "Not initialising ACRA to listen for uncaught Exceptions as this is the SendWorker process and we only send reports, we don't capture them to avoid infinite loops");
    }
    final boolean supportedAndroidVersion = Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO;
    if (!supportedAndroidVersion) {
        // NB We keep initialising so that everything is configured. But ACRA is never enabled below.
        log.w(LOG_TAG, "ACRA 4.7.0+ requires Froyo or greater. ACRA is disabled and will NOT catch crashes or send messages.");
    }
    if (mApplication != null) {
        log.w(LOG_TAG, "ACRA#init called more than once. Won't do anything more.");
        return;
    }
    mApplication = app;
    //noinspection ConstantConditions
    if (config == null) {
        log.e(LOG_TAG, "ACRA#init called but no ACRAConfiguration provided");
        return;
    }
    configProxy = config;
    final SharedPreferences prefs = new SharedPreferencesFactory(mApplication, configProxy).create();
    new LegacyFileHandler(app, prefs).updateToCurrentVersionIfNecessary();
    // Initialize ErrorReporter with all required data
    final boolean enableAcra = supportedAndroidVersion && !shouldDisableACRA(prefs);
    if (!senderServiceProcess) {
        // Indicate that ACRA is or is not listening for crashes.
        log.i(LOG_TAG, "ACRA is " + (enableAcra ? "enabled" : "disabled") + " for " + mApplication.getPackageName() + ", initializing...");
    }
    errorReporterSingleton = new ErrorReporter(mApplication, configProxy, prefs, enableAcra, supportedAndroidVersion, !senderServiceProcess);
    // NB don't check if senderServiceProcess as it will gather these reports itself.
    if (checkReportsOnApplicationStart && !senderServiceProcess) {
        final ApplicationStartupProcessor startupProcessor = new ApplicationStartupProcessor(mApplication, config);
        if (config.deleteOldUnsentReportsOnApplicationStart()) {
            startupProcessor.deleteUnsentReportsFromOldAppVersion();
        }
        if (config.deleteUnapprovedReportsOnApplicationStart()) {
            startupProcessor.deleteAllUnapprovedReportsBarOne();
        }
        if (enableAcra) {
            startupProcessor.sendApprovedReports();
        }
    }
    // We HAVE to keep a reference otherwise the listener could be garbage
    // collected:
    // http://stackoverflow.com/questions/2542938/sharedpreferences-onsharedpreferencechangelistener-not-being-called-consistently/3104265#3104265
    mPrefListener = new OnSharedPreferenceChangeListener() {

        @Override
        public void onSharedPreferenceChanged(@NonNull SharedPreferences sharedPreferences, String key) {
            if (PREF_DISABLE_ACRA.equals(key) || PREF_ENABLE_ACRA.equals(key)) {
                final boolean enableAcra = !shouldDisableACRA(sharedPreferences);
                getErrorReporter().setEnabled(enableAcra);
            }
        }
    };
    // This listener has to be set after initAcra is called to avoid a
    // NPE in ErrorReporter.disable() because
    // the context could be null at this moment.
    prefs.registerOnSharedPreferenceChangeListener(mPrefListener);
}
Also used : OnSharedPreferenceChangeListener(android.content.SharedPreferences.OnSharedPreferenceChangeListener) SharedPreferences(android.content.SharedPreferences) SharedPreferencesFactory(org.acra.prefs.SharedPreferencesFactory) LegacyFileHandler(org.acra.legacy.LegacyFileHandler) ApplicationStartupProcessor(org.acra.util.ApplicationStartupProcessor)

Example 4 with SharedPreferencesFactory

use of org.acra.prefs.SharedPreferencesFactory in project acra by ACRA.

the class CrashReportDialog method init.

@CallSuper
@Override
protected void init(@Nullable Bundle savedInstanceState) {
    scrollable = new LinearLayout(this);
    scrollable.setOrientation(LinearLayout.VERTICAL);
    sharedPreferencesFactory = new SharedPreferencesFactory(getApplicationContext(), getConfig());
    final int themeResourceId = getConfig().resDialogTheme();
    if (themeResourceId != ACRAConstants.DEFAULT_RES_VALUE)
        setTheme(themeResourceId);
    buildAndShowDialog(savedInstanceState);
}
Also used : SharedPreferencesFactory(org.acra.prefs.SharedPreferencesFactory) LinearLayout(android.widget.LinearLayout) CallSuper(android.support.annotation.CallSuper)

Aggregations

SharedPreferencesFactory (org.acra.prefs.SharedPreferencesFactory)4 SharedPreferences (android.content.SharedPreferences)3 OnSharedPreferenceChangeListener (android.content.SharedPreferences.OnSharedPreferenceChangeListener)1 CallSuper (android.support.annotation.CallSuper)1 LinearLayout (android.widget.LinearLayout)1 File (java.io.File)1 ReportingInteractionMode (org.acra.ReportingInteractionMode)1 CrashReportData (org.acra.collector.CrashReportData)1 BulkReportDeleter (org.acra.file.BulkReportDeleter)1 LegacyFileHandler (org.acra.legacy.LegacyFileHandler)1 ApplicationStartupProcessor (org.acra.util.ApplicationStartupProcessor)1