finished up Sync action

pull/14/head
Tim Su 14 years ago
parent 16bd76b18f
commit 5934d21d4a

@ -376,6 +376,12 @@
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
<receiver android:name="com.todoroo.astrid.producteev.ProducteevSyncActionExposer">
<intent-filter>
<action android:name="com.todoroo.astrid.REQUEST_SYNC_ACTIONS" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
<!-- rmilk -->
<receiver android:name="com.todoroo.astrid.rmilk.MilkFilterExposer">
@ -410,6 +416,12 @@
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
<receiver android:name="com.todoroo.astrid.rmilk.MilkSyncActionExposer">
<intent-filter>
<action android:name="com.todoroo.astrid.REQUEST_SYNC_ACTIONS" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
</application>

@ -133,17 +133,16 @@ public class AstridApiConstants {
/**
* Action name for broadcast intent requesting a listing of active
* sync providers users can activate from the menu
* sync actions users can activate from the menu
*/
public static final String BROADCAST_REQUEST_SYNC_PROVDERS = PACKAGE + ".REQUEST_SYNC_PROVIDERS";
public static final String BROADCAST_REQUEST_SYNC_ACTIONS = PACKAGE + ".REQUEST_SYNC_ACTIONS";
/**
* Action name for broadcast intent sending sync provider information back to Astrid
* @extra EXTRAS_ADDON your add-on identifier
* @extra EXTRAS_NAME label for your sync provider
* @extra EXTRAS_RESPONSE a PendingIntent to invoke synchronization
* @extra EXTRAS_RESPONSE a {@link SyncAction} to invoke synchronization
*/
public static final String BROADCAST_SEND_SYNC_PROVIDER = PACKAGE + ".SEND_SYNC_PROVIDER";
public static final String BROADCAST_SEND_SYNC_ACTIONS = PACKAGE + ".SEND_SYNC_ACTIONS";
// --- Task Actions API

@ -0,0 +1,87 @@
/**
* See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.astrid.api;
import android.app.PendingIntent;
import android.os.Parcel;
import android.os.Parcelable;
/**
* Represents an intent that can be called to perform synchronization
*
* @author Tim Su <tim@todoroo.com>
*
*/
public class SyncAction implements Parcelable {
/**
* Label
*/
public String label = null;
/**
* Intent to call when invoking this operation
*/
public PendingIntent intent = null;
/**
* Create an EditOperation object
*
* @param label
* label to display
* @param intent
* intent to invoke. {@link EXTRAS_TASK_ID} will be passed
*/
public SyncAction(String label, PendingIntent intent) {
super();
this.label = label;
this.intent = intent;
}
/**
* Returns the label of this action
*/
@Override
public String toString() {
return label;
}
// --- parcelable helpers
/**
* {@inheritDoc}
*/
public int describeContents() {
return 0;
}
/**
* {@inheritDoc}
*/
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(label);
dest.writeParcelable(intent, 0);
}
/**
* Parcelable creator
*/
public static final Parcelable.Creator<SyncAction> CREATOR = new Parcelable.Creator<SyncAction>() {
/**
* {@inheritDoc}
*/
public SyncAction createFromParcel(Parcel source) {
return new SyncAction(source.readString(), (PendingIntent)source.readParcelable(
PendingIntent.class.getClassLoader()));
}
/**
* {@inheritDoc}
*/
public SyncAction[] newArray(int size) {
return new SyncAction[size];
};
};
}

@ -0,0 +1,39 @@
/**
* See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.astrid.producteev;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import com.timsu.astrid.R;
import com.todoroo.astrid.api.AstridApiConstants;
import com.todoroo.astrid.api.SyncAction;
/**
* Exposes sync action
*
*/
public class ProducteevSyncActionExposer extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// if we aren't logged in, don't expose sync action
if(!ProducteevUtilities.INSTANCE.isLoggedIn())
return;
Intent syncIntent = new Intent(ProducteevBackgroundService.SYNC_ACTION, null,
context, ProducteevBackgroundService.class);
PendingIntent pendingIntent = PendingIntent.getService(context, 0, syncIntent, PendingIntent.FLAG_UPDATE_CURRENT);
SyncAction syncAction = new SyncAction(context.getString(R.string.producteev_PPr_header),
pendingIntent);
Intent broadcastIntent = new Intent(AstridApiConstants.BROADCAST_SEND_SYNC_ACTIONS);
broadcastIntent.putExtra(AstridApiConstants.EXTRAS_ADDON, ProducteevUtilities.IDENTIFIER);
broadcastIntent.putExtra(AstridApiConstants.EXTRAS_RESPONSE, syncAction);
context.sendBroadcast(broadcastIntent, AstridApiConstants.PERMISSION_READ);
}
}

@ -0,0 +1,39 @@
/**
* See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.astrid.rmilk;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import com.timsu.astrid.R;
import com.todoroo.astrid.api.AstridApiConstants;
import com.todoroo.astrid.api.SyncAction;
/**
* Exposes sync action
*
*/
public class MilkSyncActionExposer extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// if we aren't logged in, don't expose sync action
if(!MilkUtilities.isLoggedIn())
return;
Intent syncIntent = new Intent(MilkBackgroundService.SYNC_ACTION, null,
context, MilkBackgroundService.class);
PendingIntent pendingIntent = PendingIntent.getService(context, 0, syncIntent, PendingIntent.FLAG_UPDATE_CURRENT);
SyncAction syncAction = new SyncAction(context.getString(R.string.rmilk_MPr_header),
pendingIntent);
Intent broadcastIntent = new Intent(AstridApiConstants.BROADCAST_SEND_SYNC_ACTIONS);
broadcastIntent.putExtra(AstridApiConstants.EXTRAS_ADDON, MilkUtilities.IDENTIFIER);
broadcastIntent.putExtra(AstridApiConstants.EXTRAS_RESPONSE, syncAction);
context.sendBroadcast(broadcastIntent, AstridApiConstants.PERMISSION_READ);
}
}

@ -46,7 +46,7 @@ public class MilkNote {
/**
* Turn a note's title and text into a string
* @param title
* @param text
* @param label
* @return
*/
@SuppressWarnings("nls")

@ -1,6 +1,7 @@
package com.todoroo.astrid.activity;
import java.util.Date;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map.Entry;
import java.util.Timer;
@ -9,6 +10,7 @@ import java.util.concurrent.atomic.AtomicReference;
import android.app.AlertDialog;
import android.app.ListActivity;
import android.app.PendingIntent.CanceledException;
import android.content.BroadcastReceiver;
import android.content.ContentValues;
import android.content.Context;
@ -38,6 +40,7 @@ import android.view.inputmethod.EditorInfo;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
@ -65,6 +68,7 @@ import com.todoroo.astrid.adapter.TaskAdapter.ViewHolder;
import com.todoroo.astrid.api.AstridApiConstants;
import com.todoroo.astrid.api.Filter;
import com.todoroo.astrid.api.PermaSql;
import com.todoroo.astrid.api.SyncAction;
import com.todoroo.astrid.api.TaskAction;
import com.todoroo.astrid.api.TaskDecoration;
import com.todoroo.astrid.backup.BackupActivity;
@ -110,17 +114,17 @@ public class TaskListActivity extends ListActivity implements OnScrollListener,
private static final int MENU_ADDONS_ID = Menu.FIRST + 1;
private static final int MENU_SETTINGS_ID = Menu.FIRST + 2;
private static final int MENU_SORT_ID = Menu.FIRST + 3;
private static final int MENU_HELP_ID = Menu.FIRST + 4;
private static final int MENU_ADDON_INTENT_ID = Menu.FIRST + 5;
private static final int MENU_SYNC_ID = Menu.FIRST + 4;
private static final int MENU_HELP_ID = Menu.FIRST + 5;
private static final int MENU_ADDON_INTENT_ID = Menu.FIRST + 6;
private static final int CONTEXT_MENU_EDIT_TASK_ID = Menu.FIRST + 6;
private static final int CONTEXT_MENU_DELETE_TASK_ID = Menu.FIRST + 7;
private static final int CONTEXT_MENU_UNDELETE_TASK_ID = Menu.FIRST + 8;
private static final int CONTEXT_MENU_PURGE_TASK_ID = Menu.FIRST + 9;
private static final int CONTEXT_MENU_ADDON_INTENT_ID = Menu.FIRST + 10;
private static final int CONTEXT_MENU_EDIT_TASK_ID = Menu.FIRST + 20;
private static final int CONTEXT_MENU_DELETE_TASK_ID = Menu.FIRST + 21;
private static final int CONTEXT_MENU_UNDELETE_TASK_ID = Menu.FIRST + 22;
private static final int CONTEXT_MENU_PURGE_TASK_ID = Menu.FIRST + 23;
private static final int CONTEXT_MENU_ADDON_INTENT_ID = Menu.FIRST + 24;
/** menu code indicating the end of the context menu */
private static final int CONTEXT_MENU_DEBUG = Menu.FIRST + 11;
private static final int CONTEXT_MENU_DEBUG = Menu.FIRST + 30;
// --- constants
@ -150,6 +154,7 @@ public class TaskListActivity extends ListActivity implements OnScrollListener,
protected TaskAdapter taskAdapter = null;
protected DetailReceiver detailReceiver = new DetailReceiver();
protected RefreshReceiver refreshReceiver = new RefreshReceiver();
protected SyncActionReceiver syncActionReceiver = new SyncActionReceiver();
private ImageButton quickAddButton;
private EditText quickAddBox;
@ -158,6 +163,7 @@ public class TaskListActivity extends ListActivity implements OnScrollListener,
private int sortSort;
private final AtomicReference<String> sqlQueryTemplate = new AtomicReference<String>();
private Timer backgroundTimer;
private final LinkedHashSet<SyncAction> syncActions = new LinkedHashSet<SyncAction>();
/* ======================================================================
* ======================================================= initialization
@ -240,6 +246,12 @@ public class TaskListActivity extends ListActivity implements OnScrollListener,
R.string.TLA_menu_sort);
item.setIcon(android.R.drawable.ic_menu_sort_by_size);
if(syncActions.size() > 0) {
item = menu.add(Menu.NONE, MENU_SYNC_ID, Menu.NONE,
R.string.TLA_menu_sync);
item.setIcon(R.drawable.ic_menu_refresh);
}
item = menu.add(Menu.NONE, MENU_HELP_ID, Menu.NONE,
R.string.TLA_menu_help);
item.setIcon(android.R.drawable.ic_menu_help);
@ -430,6 +442,8 @@ public class TaskListActivity extends ListActivity implements OnScrollListener,
new IntentFilter(AstridApiConstants.BROADCAST_SEND_ACTIONS));
registerReceiver(refreshReceiver,
new IntentFilter(AstridApiConstants.BROADCAST_EVENT_REFRESH));
registerReceiver(syncActionReceiver,
new IntentFilter(AstridApiConstants.BROADCAST_SEND_SYNC_ACTIONS));
setUpBackgroundJobs();
}
@ -450,6 +464,9 @@ public class TaskListActivity extends ListActivity implements OnScrollListener,
protected class RefreshReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if(intent == null || !AstridApiConstants.BROADCAST_EVENT_REFRESH.equals(intent.getAction()))
return;
runOnUiThread(new Runnable() {
@Override
public void run() {
@ -460,6 +477,29 @@ public class TaskListActivity extends ListActivity implements OnScrollListener,
}
}
/**
* Receiver which receives sync provider intents
*
* @author Tim Su <tim@todoroo.com>
*
*/
protected class SyncActionReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if(intent == null || !AstridApiConstants.BROADCAST_SEND_SYNC_ACTIONS.equals(intent.getAction()))
return;
try {
Bundle extras = intent.getExtras();
SyncAction syncAction = extras.getParcelable(AstridApiConstants.EXTRAS_RESPONSE);
syncActions.add(syncAction);
} catch (Exception e) {
exceptionService.reportError("receive-sync-action-" + //$NON-NLS-1$
intent.getStringExtra(AstridApiConstants.EXTRAS_ADDON), e);
}
}
}
/**
* Receiver which receives detail or decoration intents
*
@ -563,6 +603,11 @@ public class TaskListActivity extends ListActivity implements OnScrollListener,
if(oldListItemSelected != ListView.INVALID_POSITION &&
oldListItemSelected < taskCursor.getCount())
getListView().setSelection(oldListItemSelected);
// also load sync actions
syncActions.clear();
Intent broadcastIntent = new Intent(AstridApiConstants.BROADCAST_REQUEST_SYNC_ACTIONS);
sendOrderedBroadcast(broadcastIntent, AstridApiConstants.PERMISSION_READ);
}
/**
@ -785,6 +830,44 @@ public class TaskListActivity extends ListActivity implements OnScrollListener,
.show();
}
private void performSyncAction() {
if(syncActions.size() == 0)
return;
if(syncActions.size() == 1) {
SyncAction syncAction = syncActions.iterator().next();
try {
syncAction.intent.send();
Toast.makeText(this, R.string.SyP_progress_toast,
Toast.LENGTH_LONG).show();
} catch (CanceledException e) {
//
}
} else {
final SyncAction[] actions = syncActions.toArray(new SyncAction[syncActions.size()]);
ArrayAdapter<SyncAction> adapter = new ArrayAdapter<SyncAction>(this,
android.R.layout.simple_spinner_dropdown_item, actions);
DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface click, int which) {
try {
actions[which].intent.send();
Toast.makeText(TaskListActivity.this, R.string.SyP_progress_toast,
Toast.LENGTH_LONG).show();
} catch (CanceledException e) {
//
}
}
};
// show a menu of available options
new AlertDialog.Builder(this)
.setTitle(R.string.SyP_label)
.setAdapter(adapter, listener)
.show().setOwnerActivity(this);
}
}
@Override
public boolean onMenuItemSelected(int featureId, final MenuItem item) {
Intent intent;
@ -805,6 +888,9 @@ public class TaskListActivity extends ListActivity implements OnScrollListener,
this, sortFlags, sortSort);
dialog.show();
return true;
case MENU_SYNC_ID:
performSyncAction();
return true;
case MENU_HELP_ID:
intent = new Intent(Intent.ACTION_VIEW,
Uri.parse("http://weloveastrid.com/help-user-guide-astrid-v3/active-tasks/")); //$NON-NLS-1$

Loading…
Cancel
Save