Search in sources :

Example 1 with BootService

use of com.ichi2.anki.services.BootService in project AnkiChinaAndroid by ankichinateam.

the class AnkiDroidApp method onCreate.

/**
 * On application creation.
 */
@Override
public void onCreate() {
    super.onCreate();
    registerActivityLifecycleCallbacks(activityLifecycleCallbacks);
    if (sInstance != null) {
        Timber.i("onCreate() called multiple times");
        // 5887 - fix crash.
        if (sInstance.getResources() == null) {
            Timber.w("Skipping re-initialisation - no resources. Maybe uninstalling app?");
            return;
        }
    }
    sInstance = this;
    // Get preferences
    SharedPreferences preferences = getSharedPrefs(this);
    Consts.LOGIN_SERVER = preferences.getInt(Consts.KEY_ANKI_ACCOUNT_SERVER, 0);
    // Setup logging and crash reporting
    acraCoreConfigBuilder = new CoreConfigurationBuilder(this);
    if (BuildConfig.DEBUG) {
        // Enable verbose error logging and do method tracing to put the Class name as log tag
        Timber.plant(new DebugTree());
        setDebugACRAConfig(preferences);
    } else {
        Timber.plant(new ProductionCrashReportingTree());
        setProductionACRAConfig(preferences);
    }
    Timber.tag(TAG);
    Timber.d("Startup - Application Start");
    // Analytics falls back to a sensible default if this is not set.
    if (ACRA.isACRASenderServiceProcess() && Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
        try {
            WebViewDebugging.setDataDirectorySuffix("acra");
        } catch (Exception e) {
            Timber.w(e, "Failed to set WebView data directory");
        }
    }
    // analytics after ACRA, they both install UncaughtExceptionHandlers but Analytics chains while ACRA does not
    UsageAnalytics.initialize(this);
    if (BuildConfig.DEBUG) {
        UsageAnalytics.setDryRun(true);
    }
    // Stop after analytics and logging are initialised.
    if (ACRA.isACRASenderServiceProcess()) {
        Timber.d("Skipping AnkiDroidApp.onCreate from ACRA sender process");
        return;
    }
    if (AdaptionUtil.isUserATestClient()) {
        UIUtils.showThemedToast(this.getApplicationContext(), getString(R.string.user_is_a_robot), false);
    }
    CardBrowserContextMenu.ensureConsistentStateWithSharedPreferences(this);
    AnkiCardContextMenu.ensureConsistentStateWithSharedPreferences(this);
    NotificationChannels.setup(getApplicationContext());
    // Configure WebView to allow file scheme pages to access cookies.
    CookieManager.setAcceptFileSchemeCookies(true);
    // Prepare Cookies to be synchronized between RAM and permanent storage.
    CompatHelper.getCompat().prepareWebViewCookies(this.getApplicationContext());
    // Set good default values for swipe detection
    final ViewConfiguration vc = ViewConfiguration.get(this);
    DEFAULT_SWIPE_MIN_DISTANCE = vc.getScaledPagingTouchSlop();
    DEFAULT_SWIPE_THRESHOLD_VELOCITY = vc.getScaledMinimumFlingVelocity();
    // Forget the last deck that was used in the CardBrowser
    CardBrowser.clearLastDeckId();
    // Create the AnkiDroid directory if missing. Send exception report if inaccessible.
    if (Permissions.hasStorageAccessPermission(this)) {
        try {
            String dir = CollectionHelper.getCurrentAnkiDroidDirectory(this);
            CollectionHelper.initializeAnkiDroidDirectory(dir);
        } catch (StorageAccessException e) {
            Timber.e(e, "Could not initialize AnkiDroid directory");
            String defaultDir = CollectionHelper.getDefaultAnkiDroidDirectory();
            if (isSdCardMounted() && CollectionHelper.getCurrentAnkiDroidDirectory(this).equals(defaultDir)) {
                // Don't send report if the user is using a custom directory as SD cards trip up here a lot
                sendExceptionReport(e, "AnkiDroidApp.onCreate");
            }
        }
    }
    Timber.i("AnkiDroidApp: Starting Services");
    new BootService().onReceive(this, new Intent(this, BootService.class));
    // Register BroadcastReceiver NotificationService
    NotificationService ns = new NotificationService();
    LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(this);
    lbm.registerReceiver(ns, new IntentFilter(NotificationService.INTENT_ACTION));
}
Also used : IntentFilter(android.content.IntentFilter) SharedPreferences(android.content.SharedPreferences) StorageAccessException(com.ichi2.anki.exception.StorageAccessException) Intent(android.content.Intent) NotificationService(com.ichi2.anki.services.NotificationService) LocalBroadcastManager(androidx.localbroadcastmanager.content.LocalBroadcastManager) ManuallyReportedException(com.ichi2.anki.exception.ManuallyReportedException) StorageAccessException(com.ichi2.anki.exception.StorageAccessException) CoreConfigurationBuilder(org.acra.config.CoreConfigurationBuilder) DebugTree(timber.log.Timber.DebugTree) ViewConfiguration(android.view.ViewConfiguration) BootService(com.ichi2.anki.services.BootService)

Example 2 with BootService

use of com.ichi2.anki.services.BootService in project AnkiChinaAndroid by ankichinateam.

the class BootService method onReceive.

@Override
public void onReceive(Context context, Intent intent) {
    if (sWasRun) {
        Timber.d("BootService - Already run");
        return;
    }
    if (!Permissions.hasStorageAccessPermission(context)) {
        Timber.w("Boot Service did not execute - no permissions");
        return;
    }
    // There are cases where the app is installed, and we have access, but nothing exist yet
    Collection col = getColSafe(context);
    if (col == null || col.getDecks() == null) {
        Timber.w("Boot Service did not execute - error loading collection");
        return;
    }
    Timber.i("Executing Boot Service");
    catchAlarmManagerErrors(context, () -> scheduleDeckReminder(context));
    catchAlarmManagerErrors(context, () -> scheduleNotification(col.getTime(), context));
    mFailedToShowNotifications = false;
    sWasRun = true;
}
Also used : Collection(com.ichi2.libanki.Collection)

Example 3 with BootService

use of com.ichi2.anki.services.BootService in project Anki-Android by ankidroid.

the class AnkiDroidApp method onCreate.

/**
 * On application creation.
 */
@Override
public void onCreate() {
    super.onCreate();
    if (sInstance != null) {
        Timber.i("onCreate() called multiple times");
        // 5887 - fix crash.
        if (sInstance.getResources() == null) {
            Timber.w("Skipping re-initialisation - no resources. Maybe uninstalling app?");
            return;
        }
    }
    sInstance = this;
    // Get preferences
    SharedPreferences preferences = getSharedPrefs(this);
    // Setup logging and crash reporting
    mAcraCoreConfigBuilder = new CoreConfigurationBuilder(this);
    if (BuildConfig.DEBUG) {
        // Enable verbose error logging and do method tracing to put the Class name as log tag
        Timber.plant(new DebugTree());
        setDebugACRAConfig(preferences);
        List<ReferenceMatcher> referenceMatchers = new ArrayList<>();
        // Add known memory leaks to 'referenceMatchers'
        matchKnownMemoryLeaks(referenceMatchers);
        // AppWatcher manual install if not already installed
        if (!AppWatcher.INSTANCE.isInstalled()) {
            AppWatcher.INSTANCE.manualInstall(this);
        }
        // Show 'Leaks' app launcher. It has been removed by default via constants.xml.
        LeakCanary.INSTANCE.showLeakDisplayActivityLauncherIcon(true);
    } else {
        Timber.plant(new ProductionCrashReportingTree());
        setProductionACRAConfig(preferences);
        disableLeakCanary();
    }
    Timber.tag(TAG);
    Timber.d("Startup - Application Start");
    // Analytics falls back to a sensible default if this is not set.
    if (ACRA.isACRASenderServiceProcess() && Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
        try {
            WebViewDebugging.setDataDirectorySuffix("acra");
        } catch (Exception e) {
            Timber.w(e, "Failed to set WebView data directory");
        }
    }
    // analytics after ACRA, they both install UncaughtExceptionHandlers but Analytics chains while ACRA does not
    UsageAnalytics.initialize(this);
    if (BuildConfig.DEBUG) {
        UsageAnalytics.setDryRun(true);
    }
    // Stop after analytics and logging are initialised.
    if (ACRA.isACRASenderServiceProcess()) {
        Timber.d("Skipping AnkiDroidApp.onCreate from ACRA sender process");
        return;
    }
    if (AdaptionUtil.isUserATestClient()) {
        UIUtils.showThemedToast(this.getApplicationContext(), getString(R.string.user_is_a_robot), false);
    }
    // make default HTML / JS debugging true for debug build and disable for unit/android tests
    if (BuildConfig.DEBUG && !AdaptionUtil.isRunningAsUnitTest()) {
        preferences.edit().putBoolean("html_javascript_debugging", true).apply();
    }
    CardBrowserContextMenu.ensureConsistentStateWithSharedPreferences(this);
    AnkiCardContextMenu.ensureConsistentStateWithSharedPreferences(this);
    NotificationChannels.setup(getApplicationContext());
    // Configure WebView to allow file scheme pages to access cookies.
    if (!acceptFileSchemeCookies()) {
        return;
    }
    // Forget the last deck that was used in the CardBrowser
    CardBrowser.clearLastDeckId();
    // Create the AnkiDroid directory if missing. Send exception report if inaccessible.
    if (Permissions.hasStorageAccessPermission(this)) {
        try {
            String dir = CollectionHelper.getCurrentAnkiDroidDirectory(this);
            CollectionHelper.initializeAnkiDroidDirectory(dir);
        } catch (StorageAccessException e) {
            Timber.e(e, "Could not initialize AnkiDroid directory");
            String defaultDir = CollectionHelper.getDefaultAnkiDroidDirectory(this);
            if (isSdCardMounted() && CollectionHelper.getCurrentAnkiDroidDirectory(this).equals(defaultDir)) {
                // Don't send report if the user is using a custom directory as SD cards trip up here a lot
                sendExceptionReport(e, "AnkiDroidApp.onCreate");
            }
        }
    }
    Timber.i("AnkiDroidApp: Starting Services");
    new BootService().onReceive(this, new Intent(this, BootService.class));
    // Register BroadcastReceiver NotificationService
    NotificationService ns = new NotificationService();
    LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(this);
    lbm.registerReceiver(ns, new IntentFilter(NotificationService.INTENT_ACTION));
}
Also used : IntentFilter(android.content.IntentFilter) ReferenceMatcher(shark.ReferenceMatcher) SharedPreferences(android.content.SharedPreferences) ArrayList(java.util.ArrayList) StorageAccessException(com.ichi2.anki.exception.StorageAccessException) Intent(android.content.Intent) NotificationService(com.ichi2.anki.services.NotificationService) LocalBroadcastManager(androidx.localbroadcastmanager.content.LocalBroadcastManager) ManuallyReportedException(com.ichi2.anki.exception.ManuallyReportedException) StorageAccessException(com.ichi2.anki.exception.StorageAccessException) CoreConfigurationBuilder(org.acra.config.CoreConfigurationBuilder) DebugTree(timber.log.Timber.DebugTree) BootService(com.ichi2.anki.services.BootService)

Aggregations

Intent (android.content.Intent)2 IntentFilter (android.content.IntentFilter)2 SharedPreferences (android.content.SharedPreferences)2 LocalBroadcastManager (androidx.localbroadcastmanager.content.LocalBroadcastManager)2 ManuallyReportedException (com.ichi2.anki.exception.ManuallyReportedException)2 StorageAccessException (com.ichi2.anki.exception.StorageAccessException)2 BootService (com.ichi2.anki.services.BootService)2 NotificationService (com.ichi2.anki.services.NotificationService)2 CoreConfigurationBuilder (org.acra.config.CoreConfigurationBuilder)2 DebugTree (timber.log.Timber.DebugTree)2 ViewConfiguration (android.view.ViewConfiguration)1 Collection (com.ichi2.libanki.Collection)1 ArrayList (java.util.ArrayList)1 ReferenceMatcher (shark.ReferenceMatcher)1