/** * Migration for existing users to assert that the "hide always" section divider exists in the * preferences. Knowing that this section will always be in the constructed list of controls * simplifies the logic a bit. * * @param c */ public static void assertHideUntilSectionExists(Context c, long latestSetVersion) { if (latestSetVersion == 0) Preferences.setBoolean(BEAST_MODE_ASSERTED_HIDE_ALWAYS, true); if (Preferences.getBoolean(BEAST_MODE_ASSERTED_HIDE_ALWAYS, false)) return; String order = Preferences.getStringValue(BEAST_MODE_ORDER_PREF); String hideSectionPref = c.getString(R.string.TEA_ctrl_hide_section_pref); if (TextUtils.isEmpty(order)) { // create preference and stick hide always at the end of it String[] items = c.getResources().getStringArray(R.array.TEA_control_sets_prefs); StringBuilder builder = new StringBuilder(); for (String item : items) { if (item.equals(hideSectionPref)) continue; builder.append(item); builder.append(BEAST_MODE_PREF_ITEM_SEPARATOR); } builder.append(hideSectionPref); builder.append(BEAST_MODE_PREF_ITEM_SEPARATOR); order = builder.toString(); } else if (!order.contains(hideSectionPref)) { order += (hideSectionPref + BEAST_MODE_PREF_ITEM_SEPARATOR); } Preferences.setString(BEAST_MODE_ORDER_PREF, order); Preferences.setBoolean(BEAST_MODE_ASSERTED_HIDE_ALWAYS, true); }
public void showTaskEditHelpPopover() { if (!AstridPreferences.canShowPopover()) return; if (!Preferences.getBoolean(R.string.p_showed_tap_task_help, false)) { quickAddBar.hideKeyboard(); getListView() .postDelayed( new Runnable() { public void run() { try { if (taskAdapter != null && taskAdapter.getCount() > 0) { final View view = getListView().getChildAt(getListView().getChildCount() - 1); if (view != null) { Activity activity = getActivity(); if (activity != null) { HelpInfoPopover.showPopover( getActivity(), view, R.string.help_popover_tap_task, null); Preferences.setBoolean(R.string.p_showed_tap_task_help, true); } } } } catch (IllegalStateException e) { // Whoops, view is gone. Try again later } } }, 1000L); } }
@Override public boolean shouldShowToast() { if (Preferences.getBoolean(AstridPreferences.P_FIRST_TASK, true)) { return false; } return super.shouldShowToast(); }
private void showTaskCreateHelpPopover() { if (!AstridPreferences.canShowPopover()) return; if (!Preferences.getBoolean(R.string.p_showed_add_task_help, false)) { Preferences.setBoolean(R.string.p_showed_add_task_help, true); HelpInfoPopover.showPopover( getActivity(), quickAddBar.getQuickAddBox(), R.string.help_popover_add_task, null); } }
private Filter[] buildSavedFilters(Context context, Resources r) { int themeFlags = ThemeService.getFilterThemeFlags(); StoreObjectDao dao = PluginServices.getStoreObjectDao(); TodorooCursor<StoreObject> cursor = dao.query( Query.select(StoreObject.PROPERTIES) .where(StoreObject.TYPE.eq(SavedFilter.TYPE)) .orderBy(Order.asc(SavedFilter.NAME))); try { ArrayList<Filter> list = new ArrayList<>(); // stock filters if (Preferences.getBoolean(R.string.p_show_recently_modified_filter, true)) { Filter recent = new Filter( r.getString(R.string.BFE_Recent), r.getString(R.string.BFE_Recent), new QueryTemplate() .where(TaskCriteria.ownedByMe()) .orderBy(Order.desc(Task.MODIFICATION_DATE)) .limit(15), null); recent.listingIcon = ((BitmapDrawable) r.getDrawable(ThemeService.getDrawable(R.drawable.filter_pencil, themeFlags))) .getBitmap(); list.add(recent); } if (cursor != null) { StoreObject savedFilter = new StoreObject(); for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) { savedFilter.readFromCursor(cursor); Filter f = SavedFilter.load(savedFilter); Intent deleteIntent = new Intent(context, DeleteActivity.class); deleteIntent.putExtra(TOKEN_FILTER_ID, savedFilter.getId()); deleteIntent.putExtra(TOKEN_FILTER_NAME, f.title); f.contextMenuLabels = new String[] {context.getString(R.string.BFE_Saved_delete)}; f.contextMenuIntents = new Intent[] {deleteIntent}; f.listingIcon = ((BitmapDrawable) r.getDrawable( ThemeService.getDrawable(R.drawable.filter_sliders, themeFlags))) .getBitmap(); list.add(f); } } return list.toArray(new Filter[list.size()]); } finally { if (cursor != null) { cursor.close(); } } }
private ActFmSyncThread(List<ClientToServerMessage<?>> messageQueue, Object syncMonitor) { DependencyInjectionService.getInstance().inject(this); this.pendingMessages = messageQueue; this.pendingCallbacks = Collections.synchronizedMap(new HashMap<ClientToServerMessage<?>, SyncMessageCallback>()); this.monitor = syncMonitor; this.syncMigration = Preferences.getBoolean(AstridNewSyncMigrator.PREF_SYNC_MIGRATION, false); this.notificationManager = new AndroidNotificationManager(ContextManager.getContext()); }
protected void addMenuItems(Menu menu, Activity activity) { boolean isTablet = AstridPreferences.useTabletLayout(activity); TaskListActivity tla = null; if (activity instanceof TaskListActivity) { tla = (TaskListActivity) activity; tla.getMainMenuPopover().clear(); } // --- sync if (tla == null || tla.getTaskEditFragment() == null) addSyncRefreshMenuItem(menu, isTablet ? ThemeService.FLAG_INVERT : 0); // --- sort if (allowResorting()) { addMenuItem( menu, R.string.TLA_menu_sort, ThemeService.getDrawable( R.drawable.icn_menu_sort_by_size, isTablet ? ThemeService.FLAG_FORCE_DARK : 0), MENU_SORT_ID, false); } // --- new filter if (Preferences.getBoolean(R.string.p_use_filters, true)) addMenuItem( menu, R.string.FLA_new_filter, ThemeService.getDrawable( R.drawable.icn_menu_filters, isTablet ? ThemeService.FLAG_FORCE_DARK : 0), MENU_NEW_FILTER_ID, false); // --- addons if (Constants.MARKET_STRATEGY.showAddonMenu()) addMenuItem( menu, R.string.TLA_menu_addons, ThemeService.getDrawable( R.drawable.icn_menu_plugins, isTablet ? ThemeService.FLAG_FORCE_DARK : 0), MENU_ADDONS_ID, false); // ask about plug-ins Intent queryIntent = new Intent(AstridApiConstants.ACTION_TASK_LIST_MENU); PackageManager pm = getActivity().getPackageManager(); List<ResolveInfo> resolveInfoList = pm.queryIntentActivities(queryIntent, 0); int length = resolveInfoList.size(); for (int i = 0; i < length; i++) { ResolveInfo resolveInfo = resolveInfoList.get(i); Intent intent = new Intent(AstridApiConstants.ACTION_TASK_LIST_MENU); intent.setClassName(resolveInfo.activityInfo.packageName, resolveInfo.activityInfo.name); addMenuItem( menu, resolveInfo.loadLabel(pm), resolveInfo.loadIcon(pm), intent, MENU_ADDON_INTENT_ID); } }
private boolean shouldShowEula(Activity activity) { if (Preferences.getBoolean(PREFERENCE_EULA_ACCEPTED, false)) return false; SharedPreferences p = activity.getSharedPreferences("eula", Activity.MODE_PRIVATE); // $NON-NLS-1$ if (p.getBoolean(PREFERENCE_EULA_ACCEPTED, false)) return false; if (taskService.countTasks() > 0) return false; return true; }
/** * Perform upgrade from one version to the next. Needs to be called on the UI thread so it can * display a progress bar and then show users a change log. * * @param from * @param to */ public void performUpgrade(final Context context, final int from) { if (from == 135) AddOnService.recordOem(); if (from > 0 && from < V3_8_2) { if (Preferences.getBoolean(R.string.p_transparent_deprecated, false)) Preferences.setString(R.string.p_theme, "transparent"); // $NON-NLS-1$ else Preferences.setString(R.string.p_theme, "black"); // $NON-NLS-1$ } if (from <= V3_9_1_1) { actFmPreferenceService.clearLastSyncDate(); } // long running tasks: pop up a progress dialog final ProgressDialog dialog; if (from < V4_0_6 && context instanceof Activity) dialog = DialogUtilities.progressDialog(context, context.getString(R.string.DLG_upgrading)); else dialog = null; final String lastSetVersionName = AstridPreferences.getCurrentVersionName(); Preferences.setInt(AstridPreferences.P_UPGRADE_FROM, from); new Thread( new Runnable() { @Override public void run() { try { // NOTE: This line should be uncommented whenever any new version requires a data // migration // TasksXmlExporter.exportTasks(context, // TasksXmlExporter.ExportType.EXPORT_TYPE_ON_UPGRADE, null, null, // lastSetVersionName); if (from < V3_0_0) new Astrid2To3UpgradeHelper().upgrade2To3(context, from); if (from < V3_1_0) new Astrid2To3UpgradeHelper().upgrade3To3_1(context, from); if (from < V3_8_3_1) new TagCaseMigrator().performTagCaseMigration(context); if (from < V3_8_4 && Preferences.getBoolean(R.string.p_showNotes, false)) taskService.clearDetails(Task.NOTES.neq("")); // $NON-NLS-1$ if (from < V4_0_6) new DueDateTimeMigrator().migrateDueTimes(); } finally { DialogUtilities.dismissDialog((Activity) context, dialog); context.sendBroadcast(new Intent(AstridApiConstants.BROADCAST_EVENT_REFRESH)); } } }) .start(); }
@Override public void onResume() { super.onResume(); getActivity() .registerReceiver( detailReceiver, new IntentFilter(AstridApiConstants.BROADCAST_SEND_DETAILS)); getActivity() .registerReceiver( detailReceiver, new IntentFilter(AstridApiConstants.BROADCAST_SEND_DECORATIONS)); getActivity() .registerReceiver( refreshReceiver, new IntentFilter(AstridApiConstants.BROADCAST_EVENT_REFRESH)); syncActionHelper.register(); if (Flags.checkAndClear(Flags.REFRESH)) { refresh(); } setUpBackgroundJobs(); if (!Preferences.getBoolean(WelcomeWalkthrough.KEY_SHOWED_WELCOME_LOGIN, false)) { Preferences.setBoolean(WelcomeWalkthrough.KEY_SHOWED_WELCOME_LOGIN, true); Intent showWelcomeLogin = new Intent(getActivity(), WelcomeWalkthrough.class); showWelcomeLogin.putExtra(ActFmLoginActivity.SHOW_TOAST, false); startActivity(showWelcomeLogin); return; } if (!Preferences.getBoolean(R.string.p_showed_add_task_help, false)) { showTaskCreateHelpPopover(); } else if (!Preferences.getBoolean(R.string.p_showed_tap_task_help, false)) { showTaskEditHelpPopover(); } else if (!Preferences.getBoolean(R.string.p_showed_lists_help, false)) { showListsHelp(); } refreshFilterCount(); initiateAutomaticSync(); }
private void userRetentionMetrics() { if (Preferences.getBoolean(AstridPreferences.P_FIRST_TASK, true)) { StatisticsService.reportEvent(StatisticsConstants.USER_FIRST_TASK); Preferences.setBoolean(AstridPreferences.P_FIRST_TASK, false); } long firstLaunchTime = Preferences.getLong(AstridPreferences.P_FIRST_LAUNCH, 0); long now = DateUtilities.now(); long timeSinceFirst = now - firstLaunchTime; if (timeSinceFirst < DateUtilities.ONE_WEEK && !Preferences.getBoolean(StatisticsConstants.TASK_ONE_WEEK, false)) { StatisticsService.reportEvent(StatisticsConstants.TASK_ONE_WEEK); Preferences.setBoolean(StatisticsConstants.TASK_ONE_WEEK, true); } else if (timeSinceFirst < 2 * DateUtilities.ONE_WEEK && !Preferences.getBoolean(StatisticsConstants.TASK_TWO_WEEKS, false)) { StatisticsService.reportEvent(StatisticsConstants.TASK_TWO_WEEKS); Preferences.setBoolean(StatisticsConstants.TASK_TWO_WEEKS, true); } else if (timeSinceFirst < 3 * DateUtilities.ONE_WEEK && !Preferences.getBoolean(StatisticsConstants.TASK_THREE_WEEKS, false)) { StatisticsService.reportEvent(StatisticsConstants.TASK_THREE_WEEKS); Preferences.setBoolean(StatisticsConstants.TASK_THREE_WEEKS, true); } }
@Override public boolean persist(Metadata item) { if (!item.containsValue(Metadata.CREATION_DATE)) item.setValue(Metadata.CREATION_DATE, DateUtilities.now()); boolean state = super.persist(item); if (Preferences.getBoolean(AstridPreferences.P_FIRST_LIST, true)) { if (state && item.getValue(Metadata.KEY).equals(TagService.KEY)) { StatisticsService.reportEvent(StatisticsConstants.USER_FIRST_LIST); Preferences.setBoolean(AstridPreferences.P_FIRST_LIST, false); } } Astrid2TaskProvider.notifyDatabaseModification(); return state; }
public void startVoiceRecognition(Context context, Fragment fragment, String currentVoiceFile) { if (speechRecordingAvailable(context) && recognizerApi != null) { recognizerApi.setTemporaryFile(currentVoiceFile); recognizerApi.start( Constants.PACKAGE, context.getString(R.string.audio_speak_now), context.getString(R.string.audio_encoding)); } else { int prompt = R.string.voice_edit_title_prompt; if (Preferences.getBoolean(R.string.p_voiceInputCreatesTask, false)) { prompt = R.string.voice_create_prompt; } voiceInputAssistant.startVoiceRecognitionActivity(fragment, prompt); } }
public void configureMicrophoneButton(final Fragment fragment, final int prompt) { if (Preferences.getBoolean(R.string.p_voiceInputEnabled, true) && VoiceRecognizer.voiceInputAvailable(ContextManager.getContext())) { voiceButton.setVisibility(View.VISIBLE); voiceButton.setOnClickListener( new OnClickListener() { @Override public void onClick(View v) { startVoiceRecognitionActivity(fragment, prompt); } }); } else { voiceButton.setVisibility(View.GONE); } }
@Override public void updatePreferences(final Preference preference, Object value) { final Resources r = getResources(); if (r.getString(R.string.p_showNotes).equals(preference.getKey())) { if (value != null && !(Boolean) value) preference.setSummary(R.string.EPr_showNotes_desc_disabled); else preference.setSummary(R.string.EPr_showNotes_desc_enabled); if ((Boolean) value != Preferences.getBoolean(preference.getKey(), false)) { taskService.clearDetails(Criterion.all); Flags.set(Flags.REFRESH); } } else if (r.getString(R.string.p_transparent).equals(preference.getKey())) { if (AndroidUtilities.getSdkVersion() < 5) { preference.setEnabled(false); preference.setSummary(R.string.EPr_transparent_desc_unsupported); } else if (value != null && !(Boolean) value) preference.setSummary(R.string.EPr_transparent_desc_disabled); else preference.setSummary(R.string.EPr_transparent_desc_enabled); } // statistics service else if (r.getString(R.string.p_statistics).equals(preference.getKey())) { if (value != null && !(Boolean) value) preference.setSummary(R.string.EPr_statistics_desc_disabled); else preference.setSummary(R.string.EPr_statistics_desc_enabled); } // voice input and output if (!addOnService.hasPowerPack()) return; if (r.getString(R.string.p_voiceInputEnabled).equals(preference.getKey())) { if (value != null && !(Boolean) value) preference.setSummary(R.string.EPr_voiceInputEnabled_desc_disabled); else preference.setSummary(R.string.EPr_voiceInputEnabled_desc_enabled); onVoiceInputStatusChanged(preference, (Boolean) value); } else if (r.getString(R.string.p_voiceRemindersEnabled).equals(preference.getKey())) { if (value != null && !(Boolean) value) preference.setSummary(R.string.EPr_voiceRemindersEnabled_desc_disabled); else preference.setSummary(R.string.EPr_voiceRemindersEnabled_desc_enabled); onVoiceReminderStatusChanged(preference, (Boolean) value); } else if (r.getString(R.string.p_voiceInputCreatesTask).equals(preference.getKey())) { if (value != null && !(Boolean) value) preference.setSummary(R.string.EPr_voiceInputCreatesTask_desc_disabled); else preference.setSummary(R.string.EPr_voiceInputCreatesTask_desc_enabled); } }
@Override public boolean persist(Metadata item) { if (!item.containsValue(Metadata.CREATION_DATE)) { item.setValue(Metadata.CREATION_DATE, DateUtilities.now()); } boolean state = super.persist(item); if (Preferences.getBoolean(AstridPreferences.P_FIRST_LIST, true)) { if (state && item.containsNonNullValue(Metadata.KEY) && item.getValue(Metadata.KEY).equals(TaskToTagMetadata.KEY)) { Preferences.setBoolean(AstridPreferences.P_FIRST_LIST, false); } } Astrid2TaskProvider.notifyDatabaseModification(); return state; }
private void showListsHelp() { if (!AstridPreferences.canShowPopover()) return; if (!Preferences.getBoolean(R.string.p_showed_lists_help, false)) { AstridActivity activity = (AstridActivity) getActivity(); if (activity != null) { if (AstridPreferences.useTabletLayout(activity)) { FilterListFragment flf = activity.getFilterListFragment(); if (flf != null) flf.showAddListPopover(); } else { ActionBar ab = activity.getSupportActionBar(); View anchor = ab.getCustomView().findViewById(R.id.lists_nav); HelpInfoPopover.showPopover(activity, anchor, R.string.help_popover_switch_lists, null); } Preferences.setBoolean(R.string.p_showed_lists_help, true); } } }
protected TaskAdapter createTaskAdapter(TodorooCursor<Task> cursor) { int resource = Preferences.getBoolean(R.string.p_taskRowStyle, false) ? R.layout.task_adapter_row_simple : R.layout.task_adapter_row; return new TaskAdapter( this, resource, cursor, sqlQueryTemplate, false, new OnCompletedTaskListener() { @Override public void onCompletedTask(Task item, boolean newState) { if (newState == true) onTaskCompleted(item); } }); }
@Override public void onReceive(Context context, Intent intent) { if (!Preferences.getBoolean(R.string.p_calendar_reminders, true)) return; try { Uri data = intent.getData(); if (data == null) return; String uriString = data.toString(); int pathIndex = uriString.indexOf("://"); if (pathIndex > 0) pathIndex += 3; else return; long eventId = Long.parseLong(uriString.substring(pathIndex)); boolean fromPostpone = CalendarAlarmScheduler.URI_PREFIX_POSTPONE.equals(data.getScheme()); if (eventId > 0) { showCalReminder(context, eventId, fromPostpone); } } catch (IllegalArgumentException e) { // Some cursor read failed, or badly formed uri e.printStackTrace(); } }
@Override public void onActivityResult(int requestCode, int resultCode, Intent data) { if (quickAddBar.onActivityResult(requestCode, resultCode, data)) return; if (requestCode == ACTIVITY_SETTINGS) { if (resultCode == EditPreferences.RESULT_CODE_THEME_CHANGED || resultCode == EditPreferences.RESULT_CODE_PERFORMANCE_PREF_CHANGED) { getActivity().finish(); getActivity().startActivity(getActivity().getIntent()); TasksWidget.updateWidgets(getActivity()); return; } else if (resultCode == SyncProviderPreferences.RESULT_CODE_SYNCHRONIZE) { Preferences.setLong( SyncActionHelper.PREF_LAST_AUTO_SYNC, 0); // Forces autosync to occur after login } } super.onActivityResult(requestCode, resultCode, data); if (!Preferences.getBoolean(R.string.p_showed_add_task_help, false)) { if (!AstridPreferences.canShowPopover()) return; quickAddBar .getQuickAddBox() .postDelayed( new Runnable() { @Override public void run() { Activity activity = getActivity(); if (activity != null) { HelpInfoPopover.showPopover( getActivity(), quickAddBar.getQuickAddBox(), R.string.help_popover_add_task, null); Preferences.setBoolean(R.string.p_showed_add_task_help, true); } } }, 1000); } }
/** Show task killer helper */ private static void showTaskKillerHelp(final Context context) { if (!Preferences.getBoolean(P_TASK_KILLER_HELP, false)) { return; } // search for task killers. if they exist, show the help! PackageManager pm = context.getPackageManager(); List<PackageInfo> apps = pm.getInstalledPackages(PackageManager.GET_PERMISSIONS); outer: for (PackageInfo app : apps) { if (app == null || app.requestedPermissions == null) { continue; } if (app.packageName.startsWith("com.android")) // $NON-NLS-1$ { continue; } for (String permission : app.requestedPermissions) { if (Manifest.permission.RESTART_PACKAGES.equals(permission)) { CharSequence appName = app.applicationInfo.loadLabel(pm); OnClickListener listener = new OnClickListener() { @Override public void onClick(DialogInterface arg0, int arg1) { Preferences.setBoolean(P_TASK_KILLER_HELP, true); } }; new AlertDialog.Builder(context) .setTitle(R.string.DLG_information_title) .setMessage(context.getString(R.string.task_killer_help, appName)) .setIcon(android.R.drawable.ic_dialog_alert) .setPositiveButton(R.string.task_killer_help_ok, listener) .show(); break outer; } } } }
@Override /** Alarm intent */ public void onReceive(Context context, Intent intent) { ContextManager.setContext(context); long id = intent.getLongExtra(ID_KEY, 0); int type = intent.getIntExtra(TYPE_KEY, (byte) 0); Resources r = context.getResources(); String reminder; if (type == ReminderService.TYPE_ALARM) reminder = getRandomReminder(r.getStringArray(R.array.reminders_alarm)); else if (Preferences.getBoolean(R.string.p_rmd_nagging, true)) { if (type == ReminderService.TYPE_DUE || type == ReminderService.TYPE_OVERDUE) reminder = getRandomReminder(r.getStringArray(R.array.reminders_due)); else if (type == ReminderService.TYPE_SNOOZE) reminder = getRandomReminder(r.getStringArray(R.array.reminders_snooze)); else reminder = getRandomReminder(r.getStringArray(R.array.reminders)); } else reminder = ""; // $NON-NLS-1$ synchronized (Notifications.class) { if (notificationManager == null) notificationManager = new AndroidNotificationManager(context); } if (!showTaskNotification(id, type, reminder)) { notificationManager.cancel((int) id); } try { VoiceOutputService.getVoiceOutputInstance().onDestroy(); } catch (VerifyError e) { // unavailable } }
/** * Creates a URL for invoking an HTTP GET/POST on the given method * * @param method * @param getParameters * @return * @throws UnsupportedEncodingException * @throws NoSuchAlgorithmException */ public String createFetchUrl(String method, Object... getParameters) throws UnsupportedEncodingException, NoSuchAlgorithmException { ArrayList<Pair<String, Object>> params = new ArrayList<Pair<String, Object>>(); for (int i = 0; i < getParameters.length; i += 2) { if (getParameters[i + 1] instanceof ArrayList) { ArrayList<?> list = (ArrayList<?>) getParameters[i + 1]; for (int j = 0; j < list.size(); j++) params.add(new Pair<String, Object>(getParameters[i].toString() + "[]", list.get(j))); } else params.add(new Pair<String, Object>(getParameters[i].toString(), getParameters[i + 1])); } params.add(new Pair<String, Object>("app_id", APP_ID)); params.add(new Pair<String, Object>("time", System.currentTimeMillis() / 1000L)); params.add(new Pair<String, Object>("api", API_VERSION)); if (token != null) { boolean foundTokenKey = false; for (Pair<String, Object> curr : params) { if (curr.getLeft().equals("token")) { foundTokenKey = true; break; } } if (!foundTokenKey) params.add(new Pair<String, Object>("token", token)); } Collections.sort( params, new Comparator<Pair<String, Object>>() { @Override public int compare(Pair<String, Object> object1, Pair<String, Object> object2) { int result = object1.getLeft().compareTo(object2.getLeft()); if (result == 0) return object1.getRight().toString().compareTo(object2.getRight().toString()); return result; } }); String url = URL; if (method.startsWith("/")) url = url.replaceFirst("/api/", ""); if (Preferences.getBoolean(R.string.actfm_https_key, false)) url = "https:" + url; else url = "http:" + url; StringBuilder requestBuilder = new StringBuilder(url).append(method).append('?'); StringBuilder sigBuilder = new StringBuilder(); for (Pair<String, Object> entry : params) { if (entry.getRight() == null) continue; String key = entry.getLeft(); String value = entry.getRight().toString(); String encoded = URLEncoder.encode(value, "UTF-8"); requestBuilder.append(key).append('=').append(encoded).append('&'); sigBuilder.append(key).append(value); } sigBuilder.append(APP_SECRET); System.err.println("SIG: " + sigBuilder); String signature = DigestUtils.md5Hex(sigBuilder.toString()); requestBuilder.append("sig").append('=').append(signature); return requestBuilder.toString(); }
private void sync() { try { int batchSize = 4; List<ClientToServerMessage<?>> messageBatch = new ArrayList<ClientToServerMessage<?>>(); while (true) { synchronized (monitor) { while ((pendingMessages.isEmpty() && !timeForBackgroundSync()) || !actFmPreferenceService.isLoggedIn() || !syncMigration) { try { if ((pendingMessages.isEmpty() || !actFmPreferenceService.isLoggedIn()) && notificationId >= 0) { notificationManager.cancel(notificationId); notificationId = -1; } monitor.wait(); AndroidUtilities.sleepDeep( 500L); // Wait briefly for large database operations to finish (e.g. adding a task // with several tags may trigger a message before all saves are done--fix // this?) if (!syncMigration) { syncMigration = Preferences.getBoolean(AstridNewSyncMigrator.PREF_SYNC_MIGRATION, false); } } catch (InterruptedException e) { // Ignored } } } boolean recordSyncSuccess = true; if (timeForBackgroundSync()) { repopulateQueueFromOutstandingTables(); enqueueMessage( BriefMe.instantiateBriefMeForClass( TaskListMetadata.class, NameMaps.PUSHED_AT_TASK_LIST_METADATA), DEFAULT_REFRESH_RUNNABLE); enqueueMessage( BriefMe.instantiateBriefMeForClass(Task.class, NameMaps.PUSHED_AT_TASKS), DEFAULT_REFRESH_RUNNABLE); enqueueMessage( BriefMe.instantiateBriefMeForClass(TagData.class, NameMaps.PUSHED_AT_TAGS), DEFAULT_REFRESH_RUNNABLE); enqueueMessage( BriefMe.instantiateBriefMeForClass(User.class, NameMaps.PUSHED_AT_USERS), DEFAULT_REFRESH_RUNNABLE); setTimeForBackgroundSync(false); } while (messageBatch.size() < batchSize && !pendingMessages.isEmpty()) { ClientToServerMessage<?> message = pendingMessages.remove(0); if (message != null) { messageBatch.add(message); } } if (!messageBatch.isEmpty() && checkForToken()) { JSONPayloadBuilder payload = new JSONPayloadBuilder(); MultipartEntity entity = new MultipartEntity(); boolean containsChangesHappened = false; for (int i = 0; i < messageBatch.size(); i++) { ClientToServerMessage<?> message = messageBatch.get(i); boolean success = payload.addMessage(message, entity); if (success) { if (message instanceof ChangesHappened) { containsChangesHappened = true; } } else { messageBatch.remove(i); i--; } } if (payload.getMessageCount() == 0) { messageBatch.clear(); continue; } setupNotification(); payload.addJSONObject(getClientVersion()); JSONArray errors = null; try { JSONObject response = actFmInvoker.postSync( payload.closeAndReturnString(), entity, containsChangesHappened, token); // process responses String time = response.optString("time"); JSONArray serverMessagesJson = response.optJSONArray("messages"); if (serverMessagesJson != null) { setWidgetSuppression(true); for (int i = 0; i < serverMessagesJson.length(); i++) { JSONObject serverMessageJson = serverMessagesJson.optJSONObject(i); if (serverMessageJson != null) { ServerToClientMessage serverMessage = ServerToClientMessage.instantiateMessage(serverMessageJson); if (serverMessage != null) { serverMessage.processMessage(time); } else { syncLog( "Index " + i + " unable to instantiate message " + serverMessageJson.toString()); } } } errors = response.optJSONArray("errors"); boolean errorsExist = (errors != null && errors.length() > 0); replayOutstandingChanges(errorsExist); setWidgetSuppression(false); } batchSize = Math.max(12, Math.min(batchSize, messageBatch.size()) * 2); if (recordSyncSuccess) { actFmPreferenceService.setLastError(null, null); actFmPreferenceService.recordSuccessfulSync(); } } catch (IOException e) { Log.e(ERROR_TAG, "IOException", e); batchSize = Math.max(batchSize / 2, 1); } Set<SyncMessageCallback> callbacksExecutedThisLoop = new HashSet<SyncMessageCallback>(); Map<Integer, List<JSONArray>> errorMap = buildErrorMap(errors); for (int i = 0; i < messageBatch.size(); i++) { ClientToServerMessage<?> message = messageBatch.get(i); try { SyncMessageCallback r = pendingCallbacks.remove(message); if (r != null && !callbacksExecutedThisLoop.contains(r)) { List<JSONArray> errorList = errorMap.get(i); if (errorList == null || errorList.isEmpty()) { r.runOnSuccess(); } else { r.runOnErrors(errorList); } callbacksExecutedThisLoop.add(r); } } catch (Exception e) { Log.e(ERROR_TAG, "Unexpected exception executing sync callback", e); } } messageBatch.clear(); } } } catch (Exception e) { // In the worst case, restart thread if something goes wrong Log.e(ERROR_TAG, "Unexpected sync thread exception", e); thread = null; startSyncThread(); } }
@Override public void onReceive(Context context, Intent intent) { if (!Preferences.getBoolean(R.string.p_rmd_enabled, true)) return; DependencyInjectionService.getInstance().inject(this); int reengagementReminders = Preferences.getInt(ReengagementService.PREF_REENGAGEMENT_COUNT, 1); Preferences.setInt(ReengagementService.PREF_REENGAGEMENT_COUNT, reengagementReminders + 1); Intent notifIntent = new Intent(context, TaskListActivity.class); QueryTemplate template = new QueryTemplate().where(TaskCriteria.activeVisibleMine()); String sql = SortHelper.adjustQueryForFlagsAndSort(template.toString(), 0, SortHelper.SORT_AUTO) + " LIMIT " + TASK_LIMIT; //$NON-NLS-1$ boolean hasTasks = false; TodorooCursor<Task> tasks = taskService.query( Query.select(Task.ID).where(TaskCriteria.activeVisibleMine()).limit(TASK_LIMIT)); try { hasTasks = tasks.getCount() > 0; } finally { tasks.close(); } String title = Notifications.getRandomReminder( context.getResources().getStringArray(R.array.rmd_reengage_notif_titles)); if (title.contains("%s")) { // $NON-NLS-1$ String name = ""; // $NON-NLS-1$ if (actFmPreferenceService.isLoggedIn()) { JSONObject thisUser = ActFmPreferenceService.thisUser(); name = thisUser.optString("first_name"); // $NON-NLS-1$ if (TextUtils.isEmpty(name)) name = thisUser.optString("name"); // $NON-NLS-1$ if (TextUtils.isEmpty(name)) name = context.getString(R.string.rmd_reengage_name_default); } title = String.format(title, name); } String text = Notifications.getRandomReminder( context .getResources() .getStringArray( hasTasks ? R.array.rmd_reengage_dialog_options : R.array.rmd_reengage_dialog_empty_options)); FilterWithCustomIntent filter = new FilterWithCustomIntent( context.getString(R.string.rmd_NoA_filter), context.getString(R.string.rmd_NoA_filter), sql, null); filter.customTaskList = new ComponentName(context, ReengagementFragment.class); filter.customExtras = new Bundle(); filter.customExtras.putString(ReengagementFragment.EXTRA_TEXT, text); notifIntent.setAction("NOTIFY_reengagement"); // $NON-NLS-1$ notifIntent.putExtra(TaskListFragment.TOKEN_FILTER, filter); notifIntent.putExtra(ReengagementFragment.EXTRA_TEXT, text); notifIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK); notifIntent.putExtra(TaskListActivity.TOKEN_SOURCE, Constants.SOURCE_REENGAGEMENT); NotificationManager manager = new AndroidNotificationManager(context); Notification notification = new Notification(R.drawable.notif_astrid, text, System.currentTimeMillis()); PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, notifIntent, PendingIntent.FLAG_UPDATE_CURRENT); notification.setLatestEventInfo(context, title, text, pendingIntent); notification.flags |= Notification.FLAG_AUTO_CANCEL; if (Preferences.getBoolean(R.string.p_rmd_persistent, true)) { notification.flags |= Notification.FLAG_NO_CLEAR | Notification.FLAG_SHOW_LIGHTS; notification.ledOffMS = 5000; notification.ledOnMS = 700; notification.ledARGB = Color.YELLOW; } else { notification.defaults = Notification.DEFAULT_LIGHTS; } manager.notify(0, notification); Flags.set(Flags.REFRESH); // Forces a reload when app launches ReengagementService.scheduleReengagementAlarm(context); }
@Override public void updatePreferences(final Preference preference, Object value) { final Resources r = getResources(); if (r.getString(R.string.p_showNotes).equals(preference.getKey())) { if (value != null && !(Boolean) value) preference.setSummary(R.string.EPr_showNotes_desc_disabled); else preference.setSummary(R.string.EPr_showNotes_desc_enabled); if ((Boolean) value != Preferences.getBoolean(preference.getKey(), false)) { taskService.clearDetails(Criterion.all); Flags.set(Flags.REFRESH); } } else if (r.getString(R.string.p_fullTaskTitle).equals(preference.getKey())) { if (value != null && (Boolean) value) preference.setSummary(R.string.EPr_fullTask_desc_enabled); else preference.setSummary(R.string.EPr_fullTask_desc_disabled); } else if (r.getString(R.string.p_theme).equals(preference.getKey())) { if (AndroidUtilities.getSdkVersion() < 5) { preference.setEnabled(false); preference.setSummary(R.string.EPr_theme_desc_unsupported); } else { int index = 0; if (value instanceof String && !TextUtils.isEmpty((String) value)) index = AndroidUtilities.indexOf( r.getStringArray(R.array.EPr_theme_settings), (String) value); if (index < 0) index = 0; preference.setSummary( getString(R.string.EPr_theme_desc, r.getStringArray(R.array.EPr_themes)[index])); } } else if (r.getString(R.string.p_theme_widget).equals(preference.getKey())) { if (AndroidUtilities.getSdkVersion() < 5) { preference.setEnabled(false); preference.setSummary(R.string.EPr_theme_desc_unsupported); } else { int index = 0; if (value instanceof String && !TextUtils.isEmpty((String) value)) index = AndroidUtilities.indexOf( r.getStringArray(R.array.EPr_theme_widget_settings), (String) value); if (index < 0) index = 0; preference.setSummary( getString(R.string.EPr_theme_desc, r.getStringArray(R.array.EPr_themes_widget)[index])); } } // pp preferences else if (booleanPreference( preference, value, R.string.p_statistics, R.string.EPr_statistics_desc_disabled, R.string.EPr_statistics_desc_enabled)) ; else if (booleanPreference( preference, value, R.string.p_autoIdea, R.string.EPr_ideaAuto_desc_disabled, R.string.EPr_ideaAuto_desc_enabled)) ; // voice input and output if (!addOnService.hasPowerPack()) return; if (r.getString(R.string.p_voiceInputEnabled).equals(preference.getKey())) { if (value != null && !(Boolean) value) preference.setSummary(R.string.EPr_voiceInputEnabled_desc_disabled); else preference.setSummary(R.string.EPr_voiceInputEnabled_desc_enabled); onVoiceInputStatusChanged(preference, (Boolean) value); } else if (r.getString(R.string.p_voiceRemindersEnabled).equals(preference.getKey())) { if (value != null && !(Boolean) value) preference.setSummary(R.string.EPr_voiceRemindersEnabled_desc_disabled); else preference.setSummary(R.string.EPr_voiceRemindersEnabled_desc_enabled); onVoiceReminderStatusChanged(preference, (Boolean) value); } else if (r.getString(R.string.p_voiceInputCreatesTask).equals(preference.getKey())) { if (value != null && !(Boolean) value) preference.setSummary(R.string.EPr_voiceInputCreatesTask_desc_disabled); else preference.setSummary(R.string.EPr_voiceInputCreatesTask_desc_enabled); } }
private void addPluginPreferences(PreferenceScreen screen) { Intent queryIntent = new Intent(AstridApiConstants.ACTION_SETTINGS); PackageManager pm = getPackageManager(); List<ResolveInfo> resolveInfoList = pm.queryIntentActivities(queryIntent, PackageManager.GET_META_DATA); int length = resolveInfoList.size(); LinkedHashMap<String, ArrayList<Preference>> categoryPreferences = new LinkedHashMap<String, ArrayList<Preference>>(); // Loop through a list of all packages (including plugins, addons) // that have a settings action String labsTitle = getString(R.string.EPr_labs_header); for (int i = 0; i < length; i++) { ResolveInfo resolveInfo = resolveInfoList.get(i); final Intent intent = new Intent(AstridApiConstants.ACTION_SETTINGS); intent.setClassName(resolveInfo.activityInfo.packageName, resolveInfo.activityInfo.name); if (MilkPreferences.class.getName().equals(resolveInfo.activityInfo.name) && !MilkUtilities.INSTANCE.isLoggedIn()) continue; if (GtasksPreferences.class.getName().equals(resolveInfo.activityInfo.name) && AmazonMarketStrategy.isKindleFire()) continue; if (ProducteevPreferences.class.getName().equals(resolveInfo.activityInfo.name) && !Preferences.getBoolean(R.string.p_third_party_addons, false) && !ProducteevUtilities.INSTANCE.isLoggedIn()) continue; Preference preference = new Preference(this); preference.setTitle(resolveInfo.activityInfo.loadLabel(pm)); if (labsTitle.equals(preference.getTitle())) preference.setSummary(R.string.EPr_labs_desc); try { Class<?> intentComponent = Class.forName(intent.getComponent().getClassName()); if (intentComponent.getSuperclass().equals(SyncProviderPreferences.class)) intentComponent = SyncProviderPreferences.class; if (PREFERENCE_REQUEST_CODES.containsKey(intentComponent)) { final int code = PREFERENCE_REQUEST_CODES.get(intentComponent); preference.setOnPreferenceClickListener( new OnPreferenceClickListener() { @Override public boolean onPreferenceClick(Preference pref) { startActivityForResult(intent, code); return true; } }); } else { preference.setIntent(intent); } } catch (ClassNotFoundException e) { preference.setIntent(intent); } String category = MetadataHelper.resolveActivityCategoryName(resolveInfo, pm); if (!categoryPreferences.containsKey(category)) categoryPreferences.put(category, new ArrayList<Preference>()); ArrayList<Preference> arrayList = categoryPreferences.get(category); arrayList.add(preference); } for (Entry<String, ArrayList<Preference>> entry : categoryPreferences.entrySet()) { Preference header = new Preference(this); header.setLayoutResource(android.R.layout.preference_category); header.setTitle(entry.getKey()); screen.addPreference(header); for (Preference preference : entry.getValue()) screen.addPreference(preference); } }
@Override public void onReceive(final Context context, Intent intent) { if (!Preferences.getBoolean(R.string.p_field_missed_calls, false)) { Preferences.clear(PREF_LAST_INCOMING_NUMBER); return; } String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE); if (TelephonyManager.EXTRA_STATE_RINGING.equals(state)) { String number = digitsOnly(intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER)); if (TextUtils.isEmpty(number)) return; Preferences.setString(PREF_LAST_INCOMING_NUMBER, number); } else if (TelephonyManager.EXTRA_STATE_IDLE.equals(state)) { final String lastNumber = Preferences.getStringValue(PREF_LAST_INCOMING_NUMBER); if (TextUtils.isEmpty(lastNumber)) { return; } Preferences.clear(PREF_LAST_INCOMING_NUMBER); new Thread() { @Override public void run() { AndroidUtilities.sleepDeep(WAIT_BEFORE_READ_LOG); Cursor calls = context .getContentResolver() .query( Calls.CONTENT_URI, new String[] {Calls.NUMBER, Calls.DATE, Calls.CACHED_NAME}, Calls.TYPE + " = ? AND " + Calls.NEW + " = ?", new String[] {Integer.toString(Calls.MISSED_TYPE), "1"}, Calls.DATE + " DESC"); try { if (calls == null) return; if (calls.moveToFirst()) { int numberIndex = calls.getColumnIndex(Calls.NUMBER); String number = calls.getString(numberIndex); // Sanity check for phone number match // in case the phone logs haven't updated for some reaosn if (!lastNumber.equals(digitsOnly(number))) { return; } // If a lot of time has passed since the most recent missed call, ignore // It could be the same person calling you back before you call them back, // but if you answer this time, the missed call will still be in the database // and will be processed again. int dateIndex = calls.getColumnIndex(Calls.DATE); long date = calls.getLong(dateIndex); if (DateUtilities.now() - date > 2 * DateUtilities.ONE_MINUTE) { return; } int nameIndex = calls.getColumnIndex(Calls.CACHED_NAME); String name = calls.getString(nameIndex); String timeString = DateUtilities.getTimeString(context, new Date(date)); long contactId = getContactIdFromNumber(context, number); Intent missedCallIntent = new Intent(context, MissedCallActivity.class); missedCallIntent.putExtra(MissedCallActivity.EXTRA_NUMBER, number); missedCallIntent.putExtra(MissedCallActivity.EXTRA_NAME, name); missedCallIntent.putExtra(MissedCallActivity.EXTRA_TIME, timeString); missedCallIntent.putExtra(MissedCallActivity.EXTRA_CONTACT_ID, contactId); missedCallIntent.setFlags( Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK); context.startActivity(missedCallIntent); } } finally { if (calls != null) calls.close(); } } }.start(); } }
private Filter[] buildSavedFilters(Context context, Resources r) { int themeFlags = ThemeService.getFilterThemeFlags(); boolean useCustomFilters = Preferences.getBoolean(R.string.p_use_filters, true); StoreObjectDao dao = PluginServices.getStoreObjectDao(); TodorooCursor<StoreObject> cursor = null; if (useCustomFilters) cursor = dao.query( Query.select(StoreObject.PROPERTIES) .where(StoreObject.TYPE.eq(SavedFilter.TYPE)) .orderBy(Order.asc(SavedFilter.NAME))); try { Filter[] list; if (useCustomFilters && cursor != null) list = new Filter[cursor.getCount() + 3]; else list = new Filter[3]; // stock filters list[0] = getTodayFilter(r); list[1] = new Filter( r.getString(R.string.BFE_Recent), r.getString(R.string.BFE_Recent), new QueryTemplate() .where(TaskCriteria.ownedByMe()) .orderBy(Order.desc(Task.MODIFICATION_DATE)) .limit(15), null); list[1].listingIcon = ((BitmapDrawable) r.getDrawable(ThemeService.getDrawable(R.drawable.filter_pencil, themeFlags))) .getBitmap(); list[2] = getAssignedByMeFilter(r); if (useCustomFilters && cursor != null) { StoreObject savedFilter = new StoreObject(); for (int i = 3; i < list.length; i++) { cursor.moveToNext(); savedFilter.readFromCursor(cursor); list[i] = SavedFilter.load(savedFilter); Intent deleteIntent = new Intent(context, DeleteActivity.class); deleteIntent.putExtra(TOKEN_FILTER_ID, savedFilter.getId()); deleteIntent.putExtra(TOKEN_FILTER_NAME, list[i].title); list[i].contextMenuLabels = new String[] {context.getString(R.string.BFE_Saved_delete)}; list[i].contextMenuIntents = new Intent[] {deleteIntent}; list[i].listingIcon = ((BitmapDrawable) r.getDrawable( ThemeService.getDrawable(R.drawable.filter_sliders, themeFlags))) .getBitmap(); } } return list; } finally { if (cursor != null) cursor.close(); } }
private void setUpInterface() { timerView = commentsBar.findViewById(R.id.timer_container); commentButton = commentsBar.findViewById(R.id.commentButton); commentField = (EditText) commentsBar.findViewById(R.id.commentField); final boolean showTimerShortcut = Preferences.getBoolean(R.string.p_show_timer_shortcut, false); if (showTimerShortcut) { commentField.setOnFocusChangeListener( new OnFocusChangeListener() { @Override public void onFocusChange(View v, boolean hasFocus) { if (hasFocus) { timerView.setVisibility(View.GONE); commentButton.setVisibility(View.VISIBLE); } else { timerView.setVisibility(View.VISIBLE); commentButton.setVisibility(View.GONE); } } }); } else { timerView.setVisibility(View.GONE); } commentField.addTextChangedListener( new TextWatcher() { @Override public void afterTextChanged(Editable s) { commentButton.setVisibility( (s.length() > 0 || pendingCommentPicture != null) ? View.VISIBLE : View.GONE); if (showTimerShortcut) timerView.setVisibility( (s.length() > 0 || pendingCommentPicture != null) ? View.GONE : View.VISIBLE); } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { // } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { // } }); commentField.setOnEditorActionListener( new OnEditorActionListener() { @Override public boolean onEditorAction(TextView view, int actionId, KeyEvent event) { if (actionId == EditorInfo.IME_NULL && commentField.getText().length() > 0) { addComment(); return true; } return false; } }); commentButton.setOnClickListener( new OnClickListener() { @Override public void onClick(View v) { addComment(); } }); final ClearImageCallback clearImage = new ClearImageCallback() { @Override public void clearImage() { pendingCommentPicture = null; pictureButton.setImageResource(cameraButton); } }; pictureButton = (ImageButton) commentsBar.findViewById(R.id.picture); pictureButton.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { if (pendingCommentPicture != null) ActFmCameraModule.showPictureLauncher(fragment, clearImage); else ActFmCameraModule.showPictureLauncher(fragment, null); respondToPicture = true; } }); if (!TextUtils.isEmpty(task.getValue(Task.NOTES))) { TextView notes = new TextView(getContext()); notes.setLinkTextColor(Color.rgb(100, 160, 255)); notes.setTextSize(18); notes.setText(task.getValue(Task.NOTES)); notes.setPadding(5, 10, 5, 10); Linkify.addLinks(notes, Linkify.ALL); } if (activity != null) { Bitmap bitmap = activity.getIntent().getParcelableExtra(TaskEditFragment.TOKEN_PICTURE_IN_PROGRESS); if (bitmap != null) { pendingCommentPicture = bitmap; pictureButton.setImageBitmap(pendingCommentPicture); } } // TODO add loading text back in // loadingText = (TextView) findViewById(R.id.loading); loadingText = new TextView(getContext()); }