diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 7e9c98234..93002759d 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -1,7 +1,7 @@ + android:versionCode="124" android:versionName="2.11.0"> diff --git a/res/values/strings.xml b/res/values/strings.xml index 0e9e1bb40..b9caf3412 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -348,10 +348,10 @@ Error Message: Information Question Done - View Task + View This Task Already Done! - Snooze - Quit + Snooze... + Go Away! Hours/minutes to snooze? Delete @@ -370,6 +370,14 @@ Some things you may not know about Astrid:\n \n Thanks for using Astrid!\n + + +It looks like you are using a task killer application! Please add Astrid to +the exclusion list for your task killer. Otherwise, if Astrid gets killed, +it will not let you know when your tasks are due.\n +\n +(note: No Astrid\'s were harmed in making this message.) + diff --git a/src/com/timsu/astrid/activities/TaskList.java b/src/com/timsu/astrid/activities/TaskList.java index 66c1f98c8..792cfbfbf 100644 --- a/src/com/timsu/astrid/activities/TaskList.java +++ b/src/com/timsu/astrid/activities/TaskList.java @@ -125,7 +125,9 @@ public class TaskList extends Activity { if(savedInstanceState != null && savedInstanceState.containsKey(LAST_ACTIVITY_TAG)) { viewFlipper.setDisplayedChild(savedInstanceState.getInt(LAST_ACTIVITY_TAG)); - variables.putAll(savedInstanceState.getBundle(LAST_BUNDLE_TAG)); + Bundle lastBundle = savedInstanceState.getBundle(LAST_BUNDLE_TAG); + if(lastBundle != null) + variables.putAll(lastBundle); } if(getIntent().hasExtra(VARIABLES_TAG)) variables.putAll(getIntent().getBundleExtra(VARIABLES_TAG)); diff --git a/src/com/timsu/astrid/activities/TaskListSubActivity.java b/src/com/timsu/astrid/activities/TaskListSubActivity.java index 158ed1691..bc371b119 100644 --- a/src/com/timsu/astrid/activities/TaskListSubActivity.java +++ b/src/com/timsu/astrid/activities/TaskListSubActivity.java @@ -47,7 +47,6 @@ import android.view.View; import android.view.ContextMenu.ContextMenuInfo; import android.view.View.OnClickListener; import android.view.View.OnCreateContextMenuListener; -import android.widget.Button; import android.widget.EditText; import android.widget.ImageButton; import android.widget.ListView; @@ -447,48 +446,38 @@ public class TaskListSubActivity extends SubActivity { Notifications.clearAllNotifications(getParent(), task .getTaskIdentifier()); - String response; - if (Preferences.shouldShowNags(getParent())) { - String[] responses = r.getStringArray(R.array.reminder_responses); - response = responses[new Random().nextInt(responses.length)]; - } else - response = r.getString(R.string.taskList_nonag_reminder); - AlertDialog dialog = new AlertDialog.Builder(getParent()).setTitle( - R.string.taskView_notifyTitle).setMessage( - task.getName() + "\n\n" + response).setIcon( - android.R.drawable.ic_dialog_alert) - - // yes, i will do it: just closes this dialog - .setPositiveButton(R.string.notify_yes, null) - - // no, i will ignore: quits application - .setNegativeButton(R.string.notify_no, - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface d, int which) { - TaskList.shouldCloseInstance = true; - closeActivity(); - } - }) + String[] strings = new String[] { + r.getString(R.string.notify_yes), + r.getString(R.string.notify_done), + r.getString(R.string.notify_snooze), + r.getString(R.string.notify_no) + }; - // snooze: sets a new temporary alert, closes application - .setNeutralButton(R.string.notify_snooze, - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface d, int which) { - snoozeAlert(task, repeatInterval, flags); - } - }) - .create(); - Button button = new Button(getParent()); - button.setText(R.string.notify_done); - button.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View arg0) { - task.setProgressPercentage(TaskModelForList.COMPLETE_PERCENTAGE); - getTaskController().saveTask(task, false); - } - }); - dialog. addContentView(button, null); - dialog.show(); + new AlertDialog.Builder(getParent()).setTitle( + task.getName()).setIcon( + android.R.drawable.ic_dialog_info) + .setSingleChoiceItems(strings, 0, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + switch(which) { + case 0: + break; + case 1: + task.setProgressPercentage(TaskModelForList.COMPLETE_PERCENTAGE); + getTaskController().saveTask(task, false); + break; + case 2: + snoozeAlert(task, repeatInterval, flags); + break; + case 3: + TaskList.shouldCloseInstance = true; + closeActivity(); + break; + } + dialog.dismiss(); + } + }) + .show(); } /** @@ -591,7 +580,7 @@ public class TaskListSubActivity extends SubActivity { if (Thread.interrupted()) return; - TaskModelForList task = i.next(); + final TaskModelForList task = i.next(); if (!filterShowDone) { if (task.isTaskCompleted()) { @@ -687,7 +676,8 @@ public class TaskListSubActivity extends SubActivity { } catch (final Exception e) { AstridUtilities.reportFlurryError("task-list-error", e); Log.e("astrid", "Error loading task list", e); - // DialogUtilities.okDialog(getParent(), "Error loading task list: " + e.getMessage() + ".\n\nOffending line: " + e.getStackTrace()[0], null); + DialogUtilities.okDialog(getParent(), "Error loading task list: " + e.getMessage() + ".\n\nOffending line: " + e.getStackTrace()[0], null); + onTaskListLoaded(); return; } diff --git a/src/com/timsu/astrid/utilities/Notifications.java b/src/com/timsu/astrid/utilities/Notifications.java index 1ca3b5f17..c893acafc 100644 --- a/src/com/timsu/astrid/utilities/Notifications.java +++ b/src/com/timsu/astrid/utilities/Notifications.java @@ -17,6 +17,7 @@ import android.content.res.Resources; import android.graphics.Color; import android.media.AudioManager; import android.net.Uri; +import android.os.Vibrator; import android.util.Log; import com.timsu.astrid.R; @@ -461,9 +462,9 @@ public class Notifications extends BroadcastReceiver { notification.sound = null; } else { if (Preferences.shouldVibrate(context) - && audioManager.getVibrateSetting(AudioManager.STREAM_RING) != - AudioManager.VIBRATE_SETTING_OFF) { - notification.vibrate = new long[] { 2000, 2000, 2000, 2000 }; + && audioManager.shouldVibrate(AudioManager.VIBRATE_TYPE_NOTIFICATION)) { + Vibrator vibrator = (Vibrator)context.getSystemService(Context.VIBRATOR_SERVICE); + vibrator.vibrate(new long[] {0, 1000, 500, 1000, 500, 1000}, 0); } else { notification.vibrate = null; } diff --git a/src/com/timsu/astrid/utilities/Preferences.java b/src/com/timsu/astrid/utilities/Preferences.java index 2ffeeca89..e349ce18a 100644 --- a/src/com/timsu/astrid/utilities/Preferences.java +++ b/src/com/timsu/astrid/utilities/Preferences.java @@ -24,6 +24,7 @@ public class Preferences { private static final String P_SYNC_LAST_SYNC_ATTEMPT = "lastsyncattempt"; private static final String P_LOCALE_LAST_NOTIFY = "locnot"; private static final String P_DID_ANDROID_AND_ME_SURVEY = "aamsurvey"; + private static final String P_TASK_KILLER_HELP = "taskkiller"; // pref values public static final int ICON_SET_PINK = 0; @@ -114,6 +115,18 @@ public class Preferences { editor.commit(); } + /** TaskKillerHelp: whether we should show task killer help */ + public static boolean shouldShowTaskKillerHelp(Context context) { + return getPrefs(context).getBoolean(P_TASK_KILLER_HELP, true); + } + + /** TaskKillerHelp: whether we should show task killer help */ + public static void setShouldShowTaskKillerHelp(Context context, boolean state) { + Editor editor = getPrefs(context).edit(); + editor.putBoolean(P_TASK_KILLER_HELP, state); + editor.commit(); + } + /** ShowRepeatHelp: whether help dialog should be shown about repeats */ public static boolean shouldShowRepeatHelp(Context context) { return getPrefs(context).getBoolean(P_SHOW_REPEAT_HELP, true); diff --git a/src/com/timsu/astrid/utilities/StartupReceiver.java b/src/com/timsu/astrid/utilities/StartupReceiver.java index 261ef09a0..b7633a9dd 100644 --- a/src/com/timsu/astrid/utilities/StartupReceiver.java +++ b/src/com/timsu/astrid/utilities/StartupReceiver.java @@ -1,5 +1,8 @@ package com.timsu.astrid.utilities; +import java.util.List; + +import android.Manifest; import android.content.BroadcastReceiver; import android.content.Context; import android.content.DialogInterface; @@ -59,6 +62,8 @@ public class StartupReceiver extends BroadcastReceiver { } } + showTaskKillerHelp(context); + Preferences.setCurrentVersion(context, finalVersion); } @@ -81,4 +86,25 @@ public class StartupReceiver extends BroadcastReceiver { 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 apps = pm.getInstalledPackages(PackageManager.GET_PERMISSIONS); + for(PackageInfo app : apps) { + for(String permission : app.requestedPermissions) { + if(Manifest.permission.RESTART_PACKAGES.equals(permission)) { + DialogUtilities.okDialog(context, context.getString(R.string.task_killer_help), new OnClickListener() { + @Override + public void onClick(DialogInterface arg0, int arg1) { + Preferences.setShouldShowTaskKillerHelp(context, true); + } + }); + } + } + } + } }