Show sync option in menu if no sync accounts are set up, then prompt user to select and log into a service

pull/14/head
Joshua Gross 14 years ago
parent fc3f3d8633
commit c42dd42676

@ -38,6 +38,12 @@ Getting Started With Development
9. Sign a [Contributors License Agreement](https://github.com/downloads/todoroo/astrid/Contributors%20Licensing%20Agreement.pdf) and send it to astrid AT todoroo.com
Testing on a device - debugging
---------------
If you have trouble running Astrid on your device, it is recommended to:
1. Fully uninstall Astrid from the device: adb uninstall com.timsu.astrid
2. Restart Eclipse
Contributors workflow
---------------

@ -8,7 +8,7 @@
<!-- android:installLocation="internalOnly"> -->
<!-- ================================================== Used Permissions = -->
<!-- for notifications -->
<uses-permission android:name="android.permission.VIBRATE"/>
<!-- for synchronization -->
@ -56,7 +56,7 @@
android:minSdkVersion="3" />
<supports-screens />
<application android:icon="@drawable/icon" android:label="@string/app_name">
<application android:icon="@drawable/icon" android:debuggable="true" android:label="@string/app_name">
<!-- ====================================================== Activities = -->

@ -31,7 +31,7 @@ import com.todoroo.astrid.data.AddOn;
*
* @author Tim Su <tim@todoroo.com>
*
*/
*/
public class CustomFilterAdapter extends ArrayAdapter<CriterionInstance> {
private final CustomFilterActivity activity;

@ -13,8 +13,8 @@ import org.weloveastrid.rmilk.MilkUtilities;
import android.content.ActivityNotFoundException;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.content.DialogInterface.OnClickListener;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.Resources;
@ -22,9 +22,9 @@ import android.net.Uri;
import android.os.Bundle;
import android.preference.CheckBoxPreference;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceCategory;
import android.preference.PreferenceScreen;
import android.preference.Preference.OnPreferenceClickListener;
import android.widget.Toast;
import com.timsu.astrid.R;
@ -39,6 +39,7 @@ import com.todoroo.andlib.widget.TodorooPreferences;
import com.todoroo.astrid.api.AstridApiConstants;
import com.todoroo.astrid.dao.Database;
import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.helper.MetadataHelper;
import com.todoroo.astrid.service.AddOnService;
import com.todoroo.astrid.service.StartupService;
import com.todoroo.astrid.service.TaskService;
@ -104,6 +105,9 @@ public class EditPreferences extends TodorooPreferences {
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
for(int i = 0; i < length; i++) {
ResolveInfo resolveInfo = resolveInfoList.get(i);
Intent intent = new Intent(AstridApiConstants.ACTION_SETTINGS);
@ -118,23 +122,7 @@ public class EditPreferences extends TodorooPreferences {
preference.setTitle(resolveInfo.activityInfo.loadLabel(pm));
preference.setIntent(intent);
// category - either from metadata, or the application name
String category = null;
if(resolveInfo.activityInfo.metaData != null &&
resolveInfo.activityInfo.metaData.containsKey(METADATA_CATEGORY)) {
int resource = resolveInfo.activityInfo.metaData.getInt(METADATA_CATEGORY, -1);
if(resource > -1) {
try {
category = pm.getResourcesForApplication(resolveInfo.activityInfo.applicationInfo).getString(resource);
} catch (Exception e) {
//
}
} else {
category = resolveInfo.activityInfo.metaData.getString(METADATA_CATEGORY);
}
}
if(category == null)
category = resolveInfo.activityInfo.applicationInfo.loadLabel(pm).toString();
String category = MetadataHelper.resolveActivityCategoryName(resolveInfo, pm);
if(!categoryPreferences.containsKey(category))
categoryPreferences.put(category, new ArrayList<Preference>());

@ -1,11 +1,12 @@
package com.todoroo.astrid.activity;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map.Entry;
import java.util.Timer;
import java.util.TimerTask;
import java.util.Map.Entry;
import java.util.concurrent.atomic.AtomicReference;
import android.app.AlertDialog;
@ -29,28 +30,28 @@ import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnKeyListener;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.View.OnClickListener;
import android.view.View.OnKeyListener;
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;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;
import android.widget.Toast;
import android.widget.AbsListView.OnScrollListener;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.TextView.OnEditorActionListener;
import com.timsu.astrid.R;
import com.todoroo.andlib.data.Property;
@ -78,6 +79,7 @@ import com.todoroo.astrid.dao.Database;
import com.todoroo.astrid.dao.TaskDao.TaskCriteria;
import com.todoroo.astrid.data.Metadata;
import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.helper.MetadataHelper;
import com.todoroo.astrid.helper.TaskListContextMenuExtensionLoader;
import com.todoroo.astrid.helper.TaskListContextMenuExtensionLoader.ContextMenuItem;
import com.todoroo.astrid.reminders.Notifications;
@ -258,11 +260,9 @@ public class TaskListActivity extends ListActivity implements OnScrollListener,
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_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);
@ -348,6 +348,7 @@ public class TaskListActivity extends ListActivity implements OnScrollListener,
}
});
// set listener for showing quick add button if text not empty
quickAddButton = ((ImageButton)findViewById(R.id.quickAddButton));
quickAddBox.addTextChangedListener(new TextWatcher() {
@ -841,10 +842,62 @@ public class TaskListActivity extends ListActivity implements OnScrollListener,
.show();
}
/**
* Intent object with custom label returned by toString.
* @author joshuagross <joshua.gross@gmail.com>
*/
private class IntentWithLabel extends Intent {
private final String label;
public IntentWithLabel (Intent in, String labelIn) {
super(in);
label = labelIn;
}
@Override
public String toString () {
return label;
}
}
private void performSyncAction() {
if(syncActions.size() == 0)
return;
if(syncActions.size() == 1) {
if (syncActions.size() == 0) {
String desiredCategory = getString(R.string.SyP_label);
// Get a list of all sync plugins and bring user to the prefs pane
// for one of them
Intent queryIntent = new Intent(AstridApiConstants.ACTION_SETTINGS);
PackageManager pm = getPackageManager();
List<ResolveInfo> resolveInfoList = pm.queryIntentActivities(
queryIntent, PackageManager.GET_META_DATA);
int length = resolveInfoList.size();
ArrayList<Intent> syncIntents = new ArrayList<Intent>();
// Loop through a list of all packages (including plugins, addons)
// that have a settings action: filter to sync actions
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);
String category = MetadataHelper.resolveActivityCategoryName(resolveInfo, pm);
if (category.equals(desiredCategory)) {
syncIntents.add(new IntentWithLabel(intent,
resolveInfo.activityInfo.loadLabel(pm).toString()));
}
}
final Intent[] actions = syncIntents.toArray(new Intent[syncIntents.size()]);
DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface click, int which) {
startActivity(actions[which]);
}
};
showSyncOptionMenu(actions, listener);
}
else if(syncActions.size() == 1) {
SyncAction syncAction = syncActions.iterator().next();
try {
syncAction.intent.send();
@ -854,9 +907,9 @@ public class TaskListActivity extends ListActivity implements OnScrollListener,
//
}
} else {
// We have >1 sync actions, pop up a dialogue so the user can
// select just one of them (only sync one at a time)
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) {
@ -869,16 +922,28 @@ public class TaskListActivity extends ListActivity implements OnScrollListener,
}
}
};
// show a menu of available options
new AlertDialog.Builder(this)
.setTitle(R.string.SyP_label)
.setAdapter(adapter, listener)
.show().setOwnerActivity(this);
showSyncOptionMenu(actions, listener);
}
}
/**
* Show menu of sync options. This is shown when you're not logged into any services, or logged into
* more than one.
* @param <TYPE>
* @param items
* @param listener
*/
private <TYPE> void showSyncOptionMenu(TYPE[] items, DialogInterface.OnClickListener listener) {
ArrayAdapter<TYPE> adapter = new ArrayAdapter<TYPE>(this,
android.R.layout.simple_spinner_dropdown_item, items);
// 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;
@ -904,7 +969,7 @@ public class TaskListActivity extends ListActivity implements OnScrollListener,
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$
Uri.parse("http://weloveastrid.com/help-user-guide-astrid-v3/active-tasks/"));
startActivity(intent);
return true;
case MENU_ADDON_INTENT_ID:
@ -966,21 +1031,21 @@ public class TaskListActivity extends ListActivity implements OnScrollListener,
if(time == 0 || time == Long.MAX_VALUE)
return;
Toast.makeText(TaskListActivity.this, "Scheduled Alarm: " + //$NON-NLS-1$
Toast.makeText(TaskListActivity.this, "Scheduled Alarm: " +
new Date(time), Toast.LENGTH_LONG).show();
ReminderService.getInstance().setScheduler(null);
}
});
ReminderService.getInstance().scheduleAlarm(task);
if(ReminderService.getInstance().getScheduler() != null)
Toast.makeText(this, "No alarms", Toast.LENGTH_LONG).show(); //$NON-NLS-1$
Toast.makeText(this, "No alarms", Toast.LENGTH_LONG).show();
ReminderService.getInstance().setScheduler(original);
return true;
}
case CONTEXT_MENU_DEBUG + 1: {
itemId = item.getGroupId();
new Notifications().showTaskNotification(itemId, 0, "test reminder"); //$NON-NLS-1$
new Notifications().showTaskNotification(itemId, 0, "test reminder");
return true;
}

@ -0,0 +1,38 @@
package com.todoroo.astrid.helper;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
/**
* @author joshuagross
*/
public class MetadataHelper {
public static String resolveActivityCategoryName (ResolveInfo resolveInfo, PackageManager pm) {
// category - either from metadata, or the application name
String category = null;
String categoryKey = "category";
if (resolveInfo.activityInfo.metaData != null && resolveInfo.activityInfo.metaData.containsKey(categoryKey)) {
int resource = resolveInfo.activityInfo.metaData.getInt(
categoryKey, -1);
if (resource > -1) {
// category stored as integer in Manifest
try {
category = pm.getResourcesForApplication(
resolveInfo.activityInfo.applicationInfo).getString(
resource);
} catch (Exception e) {
//
}
} else {
// category stored as String in Manifest
category = resolveInfo.activityInfo.metaData.getString(categoryKey);
}
}
// If category is null at this point, we use the name of the application this activity is found in
if (category == null) {
category = resolveInfo.activityInfo.applicationInfo.loadLabel(pm).toString();
}
return category;
}
}
Loading…
Cancel
Save