Fixed up start up service, moved it out of legacy, deleted home activity, and fixed various bugs

pull/14/head
Tim Su 14 years ago
parent e7205fb6cd
commit 917cb8f7c4

@ -54,16 +54,13 @@
<!-- ====================================================== Activities = -->
<!-- Activity that redirects to the appropriate home -->
<activity android:name="com.todoroo.astrid.activity.HomeActivity">
<!-- Activity that displays task list -->
<activity android:name="com.todoroo.astrid.activity.TaskListActivity"
android:theme="@style/Theme">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- Activity that displays task list -->
<activity android:name="com.todoroo.astrid.activity.TaskListActivity"
android:theme="@style/Theme">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
@ -79,9 +76,6 @@
<meta-data android:name="android.app.searchable"
android:resource="@xml/filter_list_searchable" />
</activity>
<!-- Activity that redirects to a task list, invoked by notifications -->
<activity android:name=".activities.TaskListNotify"
android:launchMode="singleTop" />
<!-- Activity that creates or edits tasks -->
<activity android:name="com.todoroo.astrid.activity.TaskEditActivity"
android:icon="@drawable/icon_add"
@ -99,7 +93,7 @@
<!-- Activity that lets users log in to sync providers -->
<activity android:name=".activities.SyncLoginActivity"/>
<!-- Activity that lets users edit app preferences -->
<activity android:name=".activities.EditPreferences"/>
<activity android:name="com.todoroo.astrid.activity.EditPreferences"/>
<!-- Activity that lets users edit synchronization preferences -->
<activity android:name=".activities.SyncPreferences"/>
<!-- Activity that Locale displays to edit tag notification settings -->
@ -122,7 +116,7 @@
</intent-filter>
</receiver>
<receiver android:name=".utilities.StartupReceiver">
<receiver android:name="com.todoroo.astrid.service.StartupService">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.DEFAULT" />
@ -153,6 +147,7 @@
<!-- ========================================================= Plugins = -->
<!-- core filters -->
<receiver android:name="com.todoroo.astrid.filters.CorePlugin">
<intent-filter>
<action android:name="com.todoroo.astrid.REQUEST_PLUGINS" />
@ -166,6 +161,7 @@
</intent-filter>
</receiver>
<!-- extended filters -->
<receiver android:name="com.todoroo.astrid.filters.ExtendedPlugin">
<intent-filter>
<action android:name="com.todoroo.astrid.REQUEST_PLUGINS" />
@ -179,6 +175,7 @@
</intent-filter>
</receiver>
<!-- tags filters -->
<receiver android:name="com.todoroo.astrid.tags.TagsPlugin">
<intent-filter>
<action android:name="com.todoroo.astrid.REQUEST_PLUGINS" />

@ -15,6 +15,13 @@ public abstract class Criterion {
this.operator = operator;
}
public static Criterion all = new Criterion(Operator.exists) {
@Override
protected void populate(StringBuilder sb) {
sb.append(true);
}
};
public static Criterion and(final Criterion criterion, final Criterion... criterions) {
return new Criterion(Operator.and) {

@ -127,4 +127,17 @@ public class AndroidUtilities {
value.getClass());
}
/**
* Return index of value in array
* @param array array to search
* @param value value to look for
* @return
*/
public static <TYPE> int indexOf(TYPE[] array, TYPE value) {
for(int i = 0; i < array.length; i++)
if(array[i].equals(value))
return i;
return -1;
}
}

@ -1,92 +0,0 @@
/**
* See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.astrid.activity;
import android.content.Intent;
import android.os.Bundle;
import com.todoroo.andlib.data.AbstractModel;
import com.todoroo.andlib.service.Autowired;
import com.todoroo.andlib.service.DependencyInjectionService;
import com.todoroo.andlib.service.ExceptionService;
import com.todoroo.astrid.dao.Database;
import com.todoroo.astrid.service.AstridDependencyInjector;
/**
* This activity displays a <code>WebView</code> that allows users to log in to the
* synchronization provider requested. A callback method determines whether
* their login was successful and therefore whether to dismiss the dialog.
*
* @author Tim Su <tim@todoroo.com>
*
*/
abstract public class AbstractModelActivity<TYPE extends AbstractModel> extends AstridActivity {
// --- bundle arguments
/**
* Action Item ID
*/
public static final String ID_TOKEN = "i"; //$NON-NLS-1$
// --- instance variables
@Autowired
protected ExceptionService exceptionService;
@Autowired
protected Database database;
protected TYPE model = null;
// --- abstract methods
abstract protected TYPE fetchModel(long id);
/**
* Load Bente Dependency Injector
*/
static {
AstridDependencyInjector.initialize();
}
public AbstractModelActivity() {
DependencyInjectionService.getInstance().inject(this);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
loadItem(getIntent());
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
loadItem(intent);
}
/**
* Loads action item from the given intent
* @param intent
*/
protected void loadItem(Intent intent) {
long idParam = intent.getLongExtra(ID_TOKEN, -1L);
if(idParam == -1) {
exceptionService.reportError("AMA-no-token", null); //$NON-NLS-1$
finish();
return;
}
database.openForReading();
model = fetchModel(idParam);
if(model == null) {
exceptionService.reportError("AMA-no-task", new NullPointerException("model")); //$NON-NLS-1$ //$NON-NLS-2$
finish();
return;
}
}
}

@ -1,104 +0,0 @@
package com.todoroo.astrid.activity;
import android.app.TabActivity;
import android.content.Intent;
import android.os.Bundle;
import com.flurry.android.FlurryAgent;
import com.todoroo.andlib.service.Autowired;
import com.todoroo.andlib.service.ContextManager;
import com.todoroo.andlib.service.DependencyInjectionService;
import com.todoroo.andlib.service.ExceptionService;
import com.todoroo.astrid.dao.Database;
import com.todoroo.astrid.service.AstridDependencyInjector;
import com.todoroo.astrid.utility.Constants;
abstract public class AbstractModelTabActivity<TYPE> extends TabActivity {
// from AstridActivity
static {
AstridDependencyInjector.initialize();
}
@Override
protected void onStart() {
super.onStart();
FlurryAgent.onStartSession(this, Constants.FLURRY_KEY);
}
@Override
protected void onStop() {
super.onStop();
FlurryAgent.onEndSession(this);
}
// from AbstractModelActivity
// --- bundle arguments
/**
* Action Item ID
*/
public static final String ID_TOKEN = "i"; //$NON-NLS-1$
// --- instance variables
@Autowired
protected ExceptionService exceptionService;
@Autowired
protected Database database;
protected TYPE model = null;
// --- abstract methods
abstract protected TYPE fetchModel(long id);
/**
* Load Bente Dependency Injector
*/
static {
AstridDependencyInjector.initialize();
}
public AbstractModelTabActivity() {
DependencyInjectionService.getInstance().inject(this);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ContextManager.setContext(this);
loadItem(getIntent());
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
loadItem(intent);
}
/**
* Loads action item from the given intent
* @param intent
*/
protected void loadItem(Intent intent) {
long idParam = intent.getLongExtra(ID_TOKEN, -1L);
if(idParam == -1) {
exceptionService.reportError("AMA-no-token", null); //$NON-NLS-1$
finish();
return;
}
database.openForReading();
model = fetchModel(idParam);
if(model == null) {
exceptionService.reportError("AMA-no-task", new NullPointerException("model")); //$NON-NLS-1$ //$NON-NLS-2$
finish();
return;
}
}
}

@ -1,46 +0,0 @@
/**
* See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.astrid.activity;
import android.app.Activity;
import android.os.Bundle;
import com.flurry.android.FlurryAgent;
import com.todoroo.andlib.service.ContextManager;
import com.todoroo.andlib.service.DependencyInjectionService;
import com.todoroo.astrid.service.AstridDependencyInjector;
import com.todoroo.astrid.utility.Constants;
/**
* General helpers for Astrid activities
*/
abstract public class AstridActivity extends Activity {
static {
AstridDependencyInjector.initialize();
}
public AstridActivity() {
DependencyInjectionService.getInstance().inject(this);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ContextManager.setContext(this);
}
@Override
protected void onStart() {
super.onStart();
FlurryAgent.onStartSession(this, Constants.FLURRY_KEY);
}
@Override
protected void onStop() {
super.onStop();
FlurryAgent.onEndSession(this);
}
}

@ -0,0 +1,225 @@
/**
* See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.astrid.activity;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map.Entry;
import android.content.Intent;
import android.content.SharedPreferences.Editor;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.Resources;
import android.os.Bundle;
import android.preference.CheckBoxPreference;
import android.preference.EditTextPreference;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.PreferenceActivity;
import android.preference.PreferenceCategory;
import android.preference.PreferenceGroup;
import android.preference.PreferenceScreen;
import android.preference.Preference.OnPreferenceChangeListener;
import android.preference.Preference.OnPreferenceClickListener;
import com.timsu.astrid.R;
import com.todoroo.andlib.service.Autowired;
import com.todoroo.andlib.service.ContextManager;
import com.todoroo.andlib.service.DependencyInjectionService;
import com.todoroo.andlib.sql.Criterion;
import com.todoroo.andlib.utility.AndroidUtilities;
import com.todoroo.andlib.utility.DialogUtilities;
import com.todoroo.astrid.api.AstridApiConstants;
import com.todoroo.astrid.dao.Database;
import com.todoroo.astrid.dao.TaskDao;
import com.todoroo.astrid.model.Task;
import com.todoroo.astrid.service.StartupService;
import com.todoroo.astrid.service.TaskService;
import com.todoroo.astrid.utility.Preferences;
/**
* Displays the preference screen for users to edit their preferences
*
* @author Tim Su <tim@todoroo.com>
*
*/
public class EditPreferences extends PreferenceActivity {
@Autowired
TaskService taskService; // for debugging
@Autowired
TaskDao taskDao;
@Autowired
Database database;
@Autowired
DialogUtilities dialogUtilities;
public EditPreferences() {
DependencyInjectionService.getInstance().inject(this);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
new StartupService().onStartupApplication(this);
ContextManager.setContext(this);
setTitle(R.string.EPr_title);
addPreferencesFromResource(R.xml.preferences);
PreferenceScreen screen = getPreferenceScreen();
initializePreference(screen);
// debugging preferences
addDebugPreferences();
// load plug-ins
Intent queryIntent = new Intent(AstridApiConstants.ACTION_SETTINGS);
PackageManager pm = getPackageManager();
List<ResolveInfo> resolveInfoList = pm.queryIntentActivities(queryIntent, 0);
int length = resolveInfoList.size();
LinkedHashMap<String, ArrayList<Preference>> applicationPreferences =
new LinkedHashMap<String, ArrayList<Preference>>();
for(int i = 0; i < length; i++) {
ResolveInfo resolveInfo = resolveInfoList.get(i);
Intent intent = new Intent(AstridApiConstants.ACTION_SETTINGS);
intent.setClassName(resolveInfo.activityInfo.packageName,
resolveInfo.activityInfo.name);
Preference preference = new Preference(this);
preference.setTitle(resolveInfo.loadLabel(pm));
preference.setIntent(intent);
String application = resolveInfo.activityInfo.applicationInfo.loadLabel(pm).toString();
if(!applicationPreferences.containsKey(application))
applicationPreferences.put(application, new ArrayList<Preference>());
ArrayList<Preference> arrayList = applicationPreferences.get(application);
arrayList.add(preference);
}
for(Entry<String, ArrayList<Preference>> entry : applicationPreferences.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);
}
}
@SuppressWarnings("nls")
private void addDebugPreferences() {
PreferenceCategory group = new PreferenceCategory(this);
group.setTitle("DEBUG");
getPreferenceScreen().addPreference(group);
Preference preference = new Preference(this);
preference.setTitle("Make Lots of Tasks");
preference.setOnPreferenceClickListener(new OnPreferenceClickListener() {
public boolean onPreferenceClick(Preference p) {
database.openForWriting();
Task task = new Task();
for(int i = 0; i < 100; i++) {
task.setId(Task.NO_ID);
task.setValue(Task.TITLE, Integer.toString(i));
taskService.save(task, false);
}
dialogUtilities.okDialog(EditPreferences.this, "done", null);
return false;
}
});
group.addPreference(preference);
preference = new Preference(this);
preference.setTitle("Delete all tasks");
preference.setOnPreferenceClickListener(new OnPreferenceClickListener() {
public boolean onPreferenceClick(Preference p) {
database.openForWriting();
taskDao.deleteWhere(Criterion.all);
dialogUtilities.okDialog(EditPreferences.this, "done", null);
return false;
}
});
group.addPreference(preference);
}
private void initializePreference(Preference preference) {
if(preference instanceof PreferenceGroup) {
PreferenceGroup group = (PreferenceGroup)preference;
for(int i = 0; i < group.getPreferenceCount(); i++) {
initializePreference(group.getPreference(i));
}
} else {
Object value = null;
if(preference instanceof ListPreference)
value = ((ListPreference)preference).getValue();
else if(preference instanceof CheckBoxPreference)
value = ((CheckBoxPreference)preference).isChecked();
else if(preference instanceof EditTextPreference)
value = ((EditTextPreference)preference).getText();
if(value != null)
updatePreferences(preference, value);
preference.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
public boolean onPreferenceChange(Preference myPreference, Object newValue) {
return updatePreferences(myPreference, newValue);
}
});
}
}
@Override
protected void onStart() {
super.onStart();
}
@Override
protected void onStop() {
super.onStop();
}
/**
*
* @param resource if null, updates all resources
*/
protected boolean updatePreferences(Preference preference, Object value) {
Resources r = getResources();
// defaults options
/*if(r.getString(R.string.EPr_default_urgency_key).equals(preference.getKey())) {
updateTaskListPreference(preference, value, r, R.array.EPr_default_urgency,
R.array.EPr_default_urgency_values, R.string.EPr_default_urgency_desc);
} else if(r.getString(R.string.EPr_default_importance_key).equals(preference.getKey())) {
updateTaskListPreference(preference, value, r, R.array.EPr_default_importance,
R.array.EPr_default_importance_values, R.string.EPr_default_importance_desc);
}*/
return true;
}
private void updateTaskListPreference(Preference preference, Object value,
Resources r, int keyArray, int valueArray, int summaryResource) {
int index = AndroidUtilities.indexOf(r.getStringArray(valueArray), (String)value);
String setting = r.getStringArray(keyArray)[index];
preference.setSummary(r.getString(summaryResource,
setting));
// if user changed the value, refresh task defaults
if(!value.equals(Preferences.getStringValue(preference.getKey()))) {
Editor editor = Preferences.getPrefs(this).edit();
editor.putString(preference.getKey(), (String)value);
editor.commit();
Task.refreshDefaultValues();
}
}
}

@ -26,7 +26,6 @@ import android.widget.ExpandableListView.ExpandableListContextMenuInfo;
import com.flurry.android.FlurryAgent;
import com.timsu.astrid.R;
import com.todoroo.andlib.service.Autowired;
import com.todoroo.andlib.service.ContextManager;
import com.todoroo.andlib.service.DependencyInjectionService;
import com.todoroo.andlib.service.ExceptionService;
import com.todoroo.andlib.utility.DialogUtilities;
@ -34,7 +33,7 @@ import com.todoroo.astrid.adapter.FilterAdapter;
import com.todoroo.astrid.api.AstridApiConstants;
import com.todoroo.astrid.api.Filter;
import com.todoroo.astrid.api.FilterListItem;
import com.todoroo.astrid.service.AstridDependencyInjector;
import com.todoroo.astrid.service.StartupService;
import com.todoroo.astrid.utility.Constants;
/**
@ -70,10 +69,6 @@ public class FilterListActivity extends ExpandableListActivity {
* ======================================================= initialization
* ====================================================================== */
static {
AstridDependencyInjector.initialize();
}
public FilterListActivity() {
DependencyInjectionService.getInstance().inject(this);
}
@ -82,7 +77,7 @@ public class FilterListActivity extends ExpandableListActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ContextManager.setContext(this);
new StartupService().onStartupApplication(this);
setContentView(R.layout.filter_list_activity);
setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL);

@ -1,82 +0,0 @@
/*
* ASTRID: Android's Simple Task Recording Dashboard
*
* Copyright (c) 2009 Tim Su
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package com.todoroo.astrid.activity;
import android.content.Intent;
import android.os.Bundle;
import com.timsu.astrid.utilities.StartupReceiver;
import com.todoroo.andlib.service.ExceptionService.TodorooUncaughtExceptionHandler;
import com.todoroo.astrid.filters.CoreFilterExposer;
/**
* HomeActivity is the primary activity for Astrid and determines which activity
* to launch next.
* <p>
* If the user is completely new, it launches {@link IntroductionActivity}.
* <p>
* If the user needs to sign in, it launches {@link SignInActivity}.
* <p>
* If the user has no coaches nd no tasks, it launches
* {@link CoachSelectorActivity}
* <p>
* Otherwise, it launches {@link TaskListActivity}.
*
* @author Tim Su <tim@todoroo.com>
*
*/
public class HomeActivity extends AstridActivity {
public static final int REQUEST_SIGN_IN = 1;
public static final int REQUEST_INTRODUCTION = 2;
/* ======================================================================
* ======================================================= initialization
* ====================================================================== */
/** Called when loading up the activity */
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// set uncaught exception handler
Thread.setDefaultUncaughtExceptionHandler(new TodorooUncaughtExceptionHandler());
// open controllers & perform application startup rituals
StartupReceiver.onStartupApplication(this);
performRedirection();
}
/* ======================================================================
* ======================================================= event handlers
* ====================================================================== */
/**
* Perform redirection to next activity
*/
private void performRedirection() {
Intent intent = new Intent(this, TaskListActivity.class);
intent.putExtra(TaskListActivity.TOKEN_FILTER, CoreFilterExposer.buildInboxFilter(getResources()));
startActivity(intent);
finish();
}
}

@ -25,8 +25,10 @@ import java.util.LinkedList;
import java.util.List;
import android.app.AlertDialog;
import android.app.TabActivity;
import android.content.ContentValues;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Resources;
import android.os.Bundle;
import android.text.Editable;
@ -67,11 +69,15 @@ import com.timsu.astrid.widget.NumberPickerDialog.OnNumberPickedListener;
import com.timsu.astrid.widget.TimeDurationControlSet.TimeDurationType;
import com.todoroo.andlib.data.TodorooCursor;
import com.todoroo.andlib.service.Autowired;
import com.todoroo.andlib.service.DependencyInjectionService;
import com.todoroo.andlib.service.ExceptionService;
import com.todoroo.andlib.utility.DateUtilities;
import com.todoroo.astrid.alarms.Alarm;
import com.todoroo.astrid.alarms.AlarmService;
import com.todoroo.astrid.dao.Database;
import com.todoroo.astrid.model.Metadata;
import com.todoroo.astrid.model.Task;
import com.todoroo.astrid.service.StartupService;
import com.todoroo.astrid.service.TaskService;
import com.todoroo.astrid.tags.TagService;
import com.todoroo.astrid.tags.TagService.Tag;
@ -84,7 +90,14 @@ import com.todoroo.astrid.tags.TagService.Tag;
* @author timsu
*
*/
public final class TaskEditActivity extends AbstractModelTabActivity<Task> {
public final class TaskEditActivity extends TabActivity {
// --- bundle tokens
/**
* Task ID
*/
public static final String ID_TOKEN = "i"; //$NON-NLS-1$
// --- request codes
@ -114,6 +127,12 @@ public final class TaskEditActivity extends AbstractModelTabActivity<Task> {
// --- services
@Autowired
ExceptionService exceptionService;
@Autowired
Database database;
@Autowired
TaskService taskService;
@ -143,6 +162,9 @@ public final class TaskEditActivity extends AbstractModelTabActivity<Task> {
// --- other instance variables
/** task model */
protected Task model = null;
/** whether task should be saved when this activity exits */
boolean shouldSaveState = true;
@ -156,24 +178,14 @@ public final class TaskEditActivity extends AbstractModelTabActivity<Task> {
* ======================================================= initialization
* ====================================================================== */
@Override
protected Task fetchModel(long id) {
database.openForWriting();
if(id == Task.NO_ID) {
FlurryAgent.onEvent("create-task"); //$NON-NLS-1$
Task task = new Task();
taskService.save(task, false);
return task;
}
FlurryAgent.onEvent("edit-task"); //$NON-NLS-1$
return taskService.fetchById(id, Task.PROPERTIES);
public TaskEditActivity() {
DependencyInjectionService.getInstance().inject(this);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
new StartupService().onStartupApplication(this);
TabHost tabHost = getTabHost();
tabHost.setPadding(0, 4, 0, 0);
@ -188,10 +200,6 @@ public final class TaskEditActivity extends AbstractModelTabActivity<Task> {
tabHost.addTab(tabHost.newTabSpec(TAB_ALERTS).setIndicator(r.getString(R.string.taskEdit_tab_alerts),
r.getDrawable(R.drawable.ic_dialog_alert_c)).setContent(R.id.tab_notification));
// weird case that has been hit before.
if(model == null)
model = new Task();
setUpUIComponents();
setUpListeners();
@ -359,10 +367,45 @@ public final class TaskEditActivity extends AbstractModelTabActivity<Task> {
* =============================================== model reading / saving
* ====================================================================== */
/**
* Loads action item from the given intent
* @param intent
*/
@SuppressWarnings("nls")
protected void loadItem(Intent intent) {
long idParam = intent.getLongExtra(ID_TOKEN, -1L);
if(idParam == -1) {
exceptionService.reportError("task-edit-no-token", null);
finish();
return;
}
database.openForReading();
if(idParam == Task.NO_ID) {
model = new Task();
taskService.save(model, false);
} else {
model = taskService.fetchById(idParam, Task.PROPERTIES);
}
if(model.getValue(Task.TITLE).length() == 0)
FlurryAgent.onEvent("create-task");
FlurryAgent.onEvent("edit-task");
if(model == null) {
exceptionService.reportError("task-edit-no-task",
new NullPointerException("model"));
finish();
return;
}
}
/** Populate UI component values from the model */
private void populateFields() {
Resources r = getResources();
loadItem(getIntent());
title.setText(model.getValue(Task.TITLE));
if(title.getText().length() > 0) {
setTitle(new StringBuilder().
@ -754,6 +797,18 @@ public final class TaskEditActivity extends AbstractModelTabActivity<Task> {
// populateFields();
}
@Override
protected void onStart() {
super.onStart();
FlurryAgent.onStartSession(this, Constants.FLURRY_KEY);
}
@Override
protected void onStop() {
super.onStop();
FlurryAgent.onEndSession(this);
}
/* ======================================================================
* ========================================== UI component helper classes
* ====================================================================== */

@ -50,8 +50,8 @@ import com.todoroo.astrid.dao.Database;
import com.todoroo.astrid.filters.CoreFilterExposer;
import com.todoroo.astrid.model.Metadata;
import com.todoroo.astrid.model.Task;
import com.todoroo.astrid.service.AstridDependencyInjector;
import com.todoroo.astrid.service.MetadataService;
import com.todoroo.astrid.service.StartupService;
import com.todoroo.astrid.service.TaskService;
import com.todoroo.astrid.utility.Constants;
@ -112,13 +112,6 @@ public class TaskListActivity extends ListActivity implements OnScrollListener {
* ======================================================= initialization
* ====================================================================== */
/**
* Load Bente Dependency Injector
*/
static {
AstridDependencyInjector.initialize();
}
public TaskListActivity() {
DependencyInjectionService.getInstance().inject(this);
}
@ -128,10 +121,12 @@ public class TaskListActivity extends ListActivity implements OnScrollListener {
protected void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
new StartupService().onStartupApplication(this);
setContentView(R.layout.task_list_activity);
Bundle extras = getIntent().getExtras();
if(extras.containsKey(TOKEN_FILTER)) {
if(extras != null && extras.containsKey(TOKEN_FILTER)) {
filter = extras.getParcelable(TOKEN_FILTER);
} else {
filter = CoreFilterExposer.buildInboxFilter(getResources());

@ -0,0 +1,162 @@
package com.todoroo.astrid.service;
import java.util.List;
import android.Manifest;
import android.app.AlarmManager;
import android.app.AlertDialog;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.DialogInterface.OnClickListener;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import com.timsu.astrid.R;
import com.timsu.astrid.appwidget.AstridAppWidgetProvider.UpdateService;
import com.timsu.astrid.sync.SynchronizationService;
import com.timsu.astrid.utilities.BackupService;
import com.timsu.astrid.utilities.Notifications;
import com.timsu.astrid.utilities.Preferences;
import com.todoroo.andlib.service.Autowired;
import com.todoroo.andlib.service.ContextManager;
import com.todoroo.andlib.service.ExceptionService;
import com.todoroo.andlib.service.ExceptionService.TodorooUncaughtExceptionHandler;
import com.todoroo.astrid.utility.Constants;
/**
* Service which handles jobs that need to be run when user's phone or Astrid
* starts up.
*
* @author Tim Su <tim@todoroo.com>
*
*/
public class StartupService extends BroadcastReceiver {
static {
AstridDependencyInjector.initialize();
}
// --- system startup
@Override
/** Called when the system is started up */
public void onReceive(Context context, Intent intent) {
ContextManager.setContext(context);
Notifications.scheduleAllAlarms(context);
}
// --- application startup
@Autowired
ExceptionService exceptionService;
@Autowired
UpgradeService upgradeService;
/**
* bit to prevent multiple initializations
*/
private static boolean hasStartedUp = false;
/** Called when this application is started up */
public synchronized void onStartupApplication(final Context context) {
if(hasStartedUp)
return;
// set uncaught exception handler
Thread.setDefaultUncaughtExceptionHandler(new TodorooUncaughtExceptionHandler());
// sets up context manager
ContextManager.setContext(context);
// read current version
int latestSetVersion = Preferences.getCurrentVersion(context);
int version = 0;
try {
PackageManager pm = context.getPackageManager();
PackageInfo pi = pm.getPackageInfo(Constants.PACKAGE, 0);
version = pi.versionCode;
} catch (Exception e) {
exceptionService.reportError("astrid-startup-package-read", e); //$NON-NLS-1$
}
// invoke upgrade service
boolean justUpgraded = latestSetVersion != version;
if(justUpgraded) {
upgradeService.performUpgrade(latestSetVersion);
Preferences.setCurrentVersion(context, version);
}
// perform startup activities in a background thread
new Thread(new Runnable() {
public void run() {
// schedule alarms
Notifications.scheduleAllAlarms(context);
// start widget updating alarm
AlarmManager am = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, UpdateService.class);
PendingIntent pendingIntent = PendingIntent.getService(context,
0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
am.setInexactRepeating(AlarmManager.RTC, 0,
Constants.WIDGET_UPDATE_INTERVAL, pendingIntent);
// start synchronization service
if(Constants.SYNCHRONIZE)
SynchronizationService.scheduleService(context);
// start backup service
BackupService.scheduleService(context);
}
}).start();
Preferences.setPreferenceDefaults(context);
// check for task killers
if(!Constants.OEM)
showTaskKillerHelp(context);
hasStartedUp = true;
}
private static void showTaskKillerHelp(final Context context) {
if(!Preferences.shouldShowTaskKillerHelp(context))
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.disableTaskKillerHelp(context);
}
};
new AlertDialog.Builder(context)
.setTitle(R.string.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;
}
}
}
}
}

@ -7,4 +7,25 @@ public final class Constants {
*/
public static final String FLURRY_KEY = "T3JAY9TV2JFMJR4YTG16"; //$NON-NLS-1$
/**
* Application Package
*/
public static final String PACKAGE = "com.timsu.astrid"; //$NON-NLS-1$
/**
* Whether this is an OEM installation
*/
public static final boolean OEM = false;
/**
* Whether to display synchronization options
*/
public static final boolean SYNCHRONIZE = !OEM;
/**
* Interval to update the widget (in order to detect hidden tasks
* becoming visible)
*/
public static final long WIDGET_UPDATE_INTERVAL = 30 * 60 * 1000L;
}

Loading…
Cancel
Save