@Override public boolean onCreate() { try { database.openForWriting(); return database.getDatabase() != null; } catch (Exception e) { exceptionService.reportError("astrid-provider", e); return false; } }
private void checkForMissingColumns() { // For some reason these properties are missing for some users. // Make them exist! try { TodorooCursor<Task> tasks = taskService.query(Query.select(Task.UUID, Task.USER_ID).limit(1)); try { System.err.println(tasks.getCount()); } finally { tasks.close(); } } catch (SQLiteException e) { database.tryAddColumn(Task.TABLE, Task.UUID, "'0'"); // $NON-NLS-1$ database.tryAddColumn(Task.TABLE, Task.USER_ID, "0"); // $NON-NLS-1$ } }
/** * Query by task. * * <p>Note that the "sortOrder" field actually can be used to append any sort of clause to your * SQL query as long as it is not also the name of a column */ @Override public Cursor query( Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { Cursor cursor = database.rawQuery(selection, null); return cursor; }
@Override public void onCreate() { DependencyInjectionService.getInstance().inject(this); database.openForReading(); cursor = getCursor(); }
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); preferences.applyThemeAndStatusBarColor(); setContentView(R.layout.custom_filter_activity); ButterKnife.inject(this); setSupportActionBar(toolbar); ActionBar supportActionBar = getSupportActionBar(); if (supportActionBar != null) { supportActionBar.setDisplayHomeAsUpEnabled(true); supportActionBar.setHomeAsUpIndicator(R.drawable.ic_close_white_24dp); supportActionBar.setTitle(R.string.FLA_new_filter); } listView = (ListView) findViewById(android.R.id.list); database.openForReading(); List<CriterionInstance> startingCriteria = new ArrayList<>(); startingCriteria.add(getStartingUniverse()); adapter = new CustomFilterAdapter(this, dialogBuilder, startingCriteria); listView.setAdapter(adapter); updateList(); setUpListeners(); }
/** Recalculate all sizes */ void updateList() { int max = 0, last = -1; StringBuilder sql = new StringBuilder(Query.select(new CountProperty()).from(Task.TABLE).toString()) .append(" WHERE "); for (int i = 0; i < adapter.getCount(); i++) { CriterionInstance instance = adapter.getItem(i); String value = instance.getValueFromCriterion(); if (value == null && instance.criterion.sql != null && instance.criterion.sql.contains("?")) { value = ""; } switch (instance.type) { case CriterionInstance.TYPE_ADD: sql.append("OR "); break; case CriterionInstance.TYPE_SUBTRACT: sql.append("AND NOT "); break; case CriterionInstance.TYPE_INTERSECT: sql.append("AND "); break; case CriterionInstance.TYPE_UNIVERSE: } // special code for all tasks universe if (instance.criterion.sql == null) { sql.append(TaskCriteria.activeAndVisible()).append(' '); } else { String subSql = instance.criterion.sql.replace("?", UnaryCriterion.sanitize(value)); subSql = PermaSql.replacePlaceholders(subSql); sql.append(Task.ID).append(" IN (").append(subSql).append(") "); } Cursor cursor = database.rawQuery(sql.toString()); try { cursor.moveToNext(); instance.start = last == -1 ? cursor.getInt(0) : last; instance.end = cursor.getInt(0); last = instance.end; max = Math.max(max, last); } finally { cursor.close(); } } for (int i = 0; i < adapter.getCount(); i++) { CriterionInstance instance = adapter.getItem(i); instance.max = max; } adapter.notifyDataSetInvalidated(); }
/** * Loads action item from the given intent * * @param intent */ @SuppressWarnings("nls") protected void loadItem(Intent intent) { if (model != null) { // came from bundle isNewTask = (model.getValue(Task.TITLE).length() == 0); return; } long idParam = intent.getLongExtra(TOKEN_ID, -1L); database.openForReading(); if (idParam > -1L) { model = taskService.fetchById(idParam, Task.PROPERTIES); } // not found by id or was never passed an id if (model == null) { String valuesAsString = intent.getStringExtra(TOKEN_VALUES); ContentValues values = null; try { if (valuesAsString != null) values = AndroidUtilities.contentValuesFromSerializedString(valuesAsString); } catch (Exception e) { // oops, can't serialize } model = TaskListActivity.createWithValues(values, null, taskService, metadataService); } if (model.getValue(Task.TITLE).length() == 0) { StatisticsService.reportEvent("create-task"); isNewTask = true; // set deletion date until task gets a title model.setValue(Task.DELETION_DATE, DateUtilities.now()); } else { StatisticsService.reportEvent("edit-task"); } if (model == null) { exceptionService.reportError("task-edit-no-task", new NullPointerException("model")); finish(); return; } // clear notification Notifications.cancelNotifications(model.getId()); }
/** If database exists, no tasks but metadata, and a backup file exists, restore it */ private void databaseRestoreIfEmpty(Context context) { try { if (AstridPreferences.getCurrentVersion() >= UpgradeService.V3_0_0 && !context.getDatabasePath(database.getName()).exists()) { // we didn't have a database! restore latest file File directory = BackupConstants.defaultExportDirectory(); if (!directory.exists()) { return; } File[] children = directory.listFiles(); AndroidUtilities.sortFilesByDateDesc(children); if (children.length > 0) { TasksXmlImporter.importTasks(context, children[0].getAbsolutePath(), null); } } } catch (Exception e) { Log.w("astrid-database-restore", e); // $NON-NLS-1$ } }
/** * Perform the upgrade from Astrid 2 to Astrid 3 * * @param context2 */ @SuppressWarnings("deprecation") public void upgrade2To3(final Context context, final int from) { // if from < 1 (we don't know what version, and database exists, leave it alone) if (from < 1 && checkIfDatabaseExists(context, database.getName())) return; // if you don't have a legacy task table, skip this step if (!checkIfDatabaseExists(context, tasksTable)) return; // else, if there's already a database table, clear it out (!!!) if (checkIfDatabaseExists(context, database.getName())) context.deleteDatabase(database.getName()); database.openForWriting(); // initiate a backup String backupFile = legacyBackup(); try { // --- upgrade tasks table HashMap<String, Property<?>> propertyMap = new HashMap<String, Property<?>>(); propertyMap.put("_id", Task.ID); // $NON-NLS-1$ propertyMap.put(LegacyTaskModel.NAME, Task.TITLE); propertyMap.put(LegacyTaskModel.NOTES, Task.NOTES); // (don't update progress percentage, we don't use this anymore) propertyMap.put(LegacyTaskModel.IMPORTANCE, Task.IMPORTANCE); propertyMap.put(LegacyTaskModel.ESTIMATED_SECONDS, Task.ESTIMATED_SECONDS); propertyMap.put(LegacyTaskModel.ELAPSED_SECONDS, Task.ELAPSED_SECONDS); propertyMap.put(LegacyTaskModel.TIMER_START, Task.TIMER_START); propertyMap.put(LegacyTaskModel.DEFINITE_DUE_DATE, Task.DUE_DATE); propertyMap.put(LegacyTaskModel.HIDDEN_UNTIL, Task.HIDE_UNTIL); propertyMap.put(LegacyTaskModel.POSTPONE_COUNT, Task.POSTPONE_COUNT); propertyMap.put(LegacyTaskModel.NOTIFICATIONS, Task.REMINDER_PERIOD); propertyMap.put(LegacyTaskModel.NOTIFICATION_FLAGS, Task.REMINDER_FLAGS); propertyMap.put(LegacyTaskModel.LAST_NOTIFIED, Task.REMINDER_LAST); propertyMap.put(LegacyTaskModel.REPEAT, Task.RECURRENCE); propertyMap.put(LegacyTaskModel.CREATION_DATE, Task.CREATION_DATE); propertyMap.put(LegacyTaskModel.COMPLETION_DATE, Task.COMPLETION_DATE); propertyMap.put(LegacyTaskModel.CALENDAR_URI, Task.CALENDAR_URI); propertyMap.put(LegacyTaskModel.FLAGS, Task.FLAGS); upgradeTable(context, tasksTable, propertyMap, new Task(), taskDao); // --- upgrade tags tables migrateTagsToMetadata(); // --- upgrade alerts AlarmDatabase alarmsDatabase = new AlarmDatabase(); alarmsDatabase.openForWriting(); propertyMap.clear(); propertyMap.put("_id", TransitionalAlarm.ID); // $NON-NLS-1$ propertyMap.put(LegacyAlertModel.TASK, TransitionalAlarm.TASK); propertyMap.put(LegacyAlertModel.DATE, TransitionalAlarm.TIME); upgradeTable( context, alertsTable, propertyMap, new TransitionalAlarm(), alarmsDatabase.getDao()); alarmsDatabase.close(); // --- upgrade RTM sync mappings migrateSyncMappingToMetadata(); // --- clean up database metadataService.cleanup(); // --- upgrade properties SharedPreferences prefs = Preferences.getPrefs(context); Editor editor = prefs.edit(); int random = Preferences.getIntegerFromString(R.string.p_rmd_default_random_hours, -1); if (random != -1) { // convert days => hours editor.putString( context.getString(R.string.p_rmd_default_random_hours), Integer.toString(random * 24)); } } catch (Exception e) { exceptionService.reportError("backup-error", e); // $NON-NLS-1$ if (backupFile != null) { // try to restore the latest XML TasksXmlImporter.importTasks(context, backupFile, null); } } }
/** * Perform the upgrade from Astrid 3 to 3.1 * * @param context * @param upgradeService * @param from */ public void upgrade3To3_1(final Context context, final int from) { if (!checkIfDatabaseExists(context, alertsTable)) return; database.openForWriting(); migrateAlarmsToMetadata(); }
/** * If primary upgrade doesn't work for some reason (corrupt SharedPreferences, for example), this * will catch some cases */ public void performSecondaryUpgrade(Context context) { if (!context.getDatabasePath(database.getName()).exists() && context.getDatabasePath("tasks").exists()) { // $NON-NLS-1$ new Astrid2To3UpgradeHelper().upgrade2To3(context, 1); } }
@SuppressWarnings("nls") public RemoteViews buildUpdate(Context context, int widgetId) { DependencyInjectionService.getInstance().inject(this); RemoteViews views = null; views = new RemoteViews(context.getPackageName(), R.layout.widget_initialized); int[] textIDs = TEXT_IDS; int[] separatorIDs = SEPARATOR_IDS; int numberOfTasks = 5; for (int i = 0; i < textIDs.length; i++) views.setTextViewText(textIDs[i], ""); TodorooCursor<Task> cursor = null; Filter filter = null; try { filter = getFilter(widgetId); views.setTextViewText(R.id.widget_title, filter.title); SharedPreferences publicPrefs = AstridPreferences.getPublicPrefs(this); int flags = publicPrefs.getInt(SortHelper.PREF_SORT_FLAGS, 0); int sort = publicPrefs.getInt(SortHelper.PREF_SORT_SORT, 0); String query = SortHelper.adjustQueryForFlagsAndSort(filter.sqlQuery, flags, sort) .replaceAll("LIMIT \\d+", "") + " LIMIT " + numberOfTasks; database.openForReading(); cursor = taskService.fetchFiltered( query, null, Task.ID, Task.TITLE, Task.DUE_DATE, Task.COMPLETION_DATE); Task task = new Task(); for (int i = 0; i < cursor.getCount() && i < numberOfTasks; i++) { cursor.moveToPosition(i); task.readFromCursor(cursor); String textContent = ""; int textColor = Color.WHITE; textContent = task.getValue(Task.TITLE); if (task.isCompleted()) textColor = context.getResources().getColor(R.color.task_list_done); else if (task.hasDueDate() && task.getValue(Task.DUE_DATE) < DateUtilities.now()) textColor = context.getResources().getColor(R.color.task_list_overdue); if (i > 0) views.setViewVisibility(separatorIDs[i - 1], View.VISIBLE); views.setTextViewText(textIDs[i], textContent); views.setTextColor(textIDs[i], textColor); } for (int i = cursor.getCount() - 1; i < separatorIDs.length; i++) { if (i >= 0) views.setViewVisibility(separatorIDs[i], View.INVISIBLE); } } catch (Exception e) { // can happen if database is not ready Log.e("WIDGET-UPDATE", "Error updating widget", e); } finally { if (cursor != null) cursor.close(); } updateForScreenSize(views); Intent listIntent = new Intent(context, TaskListActivity.class); String customIntent = Preferences.getStringValue(WidgetConfigActivity.PREF_CUSTOM_INTENT + widgetId); if (customIntent != null) { listIntent.setComponent(ComponentName.unflattenFromString(customIntent)); String serializedExtras = Preferences.getStringValue(WidgetConfigActivity.PREF_CUSTOM_EXTRAS + widgetId); Bundle extras = AndroidUtilities.bundleFromSerializedString(serializedExtras); listIntent.putExtras(extras); } listIntent.putExtra(TaskListActivity.TOKEN_SOURCE, Constants.SOURCE_WIDGET); listIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK); if (filter != null) { listIntent.putExtra(TaskListActivity.TOKEN_FILTER, filter); listIntent.setAction("L" + widgetId + filter.sqlQuery); } PendingIntent pendingIntent = PendingIntent.getActivity( context, widgetId, listIntent, PendingIntent.FLAG_CANCEL_CURRENT); views.setOnClickPendingIntent(R.id.taskbody, pendingIntent); Intent editIntent = new Intent(context, TaskEditActivity.class); editIntent.setFlags( Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); if (filter != null && filter.valuesForNewTasks != null) { String values = AndroidUtilities.contentValuesToSerializedString(filter.valuesForNewTasks); editIntent.putExtra(TaskEditActivity.TOKEN_VALUES, values); editIntent.setType(values); } pendingIntent = PendingIntent.getActivity(context, 0, editIntent, 0); views.setOnClickPendingIntent(R.id.widget_button, pendingIntent); return views; }
/** Called when this application is started up */ public synchronized void onStartupApplication(final Activity context) { if (hasStartedUp || context == null) { return; } // sets up context manager ContextManager.setContext(context); try { database.openForWriting(); checkForMissingColumns(); } catch (SQLiteException e) { handleSQLiteError(context, e); return; } // show notification if reminders are silenced if (context instanceof Activity) { AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); if (!Preferences.getBoolean(R.string.p_rmd_enabled, true)) { Toast.makeText(context, R.string.TLA_notification_disabled, Toast.LENGTH_LONG).show(); } else if (audioManager.getStreamVolume(AudioManager.STREAM_NOTIFICATION) == 0) { Toast.makeText(context, R.string.TLA_notification_volume_low, Toast.LENGTH_LONG).show(); } } // read current version int latestSetVersion = 0; try { latestSetVersion = AstridPreferences.getCurrentVersion(); } catch (Exception e) { exceptionService.reportError("astrid-startup-version-read", e); // $NON-NLS-1$ } if (latestSetVersion == 0) { if (Preferences.getLong(AstridPreferences.P_FIRST_LAUNCH, -1) < 0) { Preferences.setLong(AstridPreferences.P_FIRST_LAUNCH, DateUtilities.now()); } } BeastModePreferences.assertHideUntilSectionExists(context, latestSetVersion); int version = 0; String versionName = "0"; // $NON-NLS-1$ try { PackageManager pm = context.getPackageManager(); PackageInfo pi = pm.getPackageInfo(Constants.PACKAGE, PackageManager.GET_META_DATA); version = pi.versionCode; versionName = pi.versionName; } catch (Exception e) { exceptionService.reportError("astrid-startup-package-read", e); // $NON-NLS-1$ } Log.i( "astrid", "Astrid Startup. " + latestSetVersion + //$NON-NLS-1$ //$NON-NLS-2$ " => " + version); //$NON-NLS-1$ databaseRestoreIfEmpty(context); // invoke upgrade service boolean justUpgraded = latestSetVersion != version; if (justUpgraded && version > 0) { if (latestSetVersion > 0) { upgradeService.performUpgrade(context, latestSetVersion); } AstridPreferences.setCurrentVersion(version); AstridPreferences.setCurrentVersionName(versionName); } final int finalLatestVersion = latestSetVersion; initializeDatabaseListeners(); // perform startup activities in a background thread new Thread( new Runnable() { @Override public void run() { taskService.cleanup(); // if sync ongoing flag was set, clear it gtasksPreferenceService.stopOngoing(); // perform initialization ReminderStartupReceiver.startReminderSchedulingService(context); BackupService.scheduleService(context); gtasksSyncService.initialize(); // get and display update messages if (finalLatestVersion != 0) { // new UpdateMessageService(context).processUpdates(); } } }) .start(); AstridPreferences.setPreferenceDefaults(); CalendarStartupReceiver.scheduleCalendarAlarms( context, false); // This needs to be after set preference defaults for the purposes of ab testing showTaskKillerHelp(context); hasStartedUp = true; }