From 7770852144913376cc26b6728b5d4977eb35c8a2 Mon Sep 17 00:00:00 2001 From: Tim Su Date: Mon, 7 Feb 2011 14:48:17 -0800 Subject: [PATCH] Link action is totally awesome. Now you can get your links via task action --- astrid/AndroidManifest.xml | 7 ++ .../astrid/core/LinkActionExposer.java | 100 ++++++++++++++++++ .../todoroo/astrid/adapter/TaskAdapter.java | 23 ++-- .../helper/TaskAdapterAddOnManager.java | 16 +-- 4 files changed, 129 insertions(+), 17 deletions(-) create mode 100644 astrid/plugin-src/com/todoroo/astrid/core/LinkActionExposer.java diff --git a/astrid/AndroidManifest.xml b/astrid/AndroidManifest.xml index aa1e28bcf..5328b79ec 100644 --- a/astrid/AndroidManifest.xml +++ b/astrid/AndroidManifest.xml @@ -520,6 +520,13 @@ + + + + + + + diff --git a/astrid/plugin-src/com/todoroo/astrid/core/LinkActionExposer.java b/astrid/plugin-src/com/todoroo/astrid/core/LinkActionExposer.java new file mode 100644 index 000000000..af0085f35 --- /dev/null +++ b/astrid/plugin-src/com/todoroo/astrid/core/LinkActionExposer.java @@ -0,0 +1,100 @@ +/** + * See the file "LICENSE" for the full license governing this code. + */ +package com.todoroo.astrid.core; + +import java.util.List; + +import android.app.PendingIntent; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.graphics.Bitmap; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; +import android.net.Uri; +import android.text.Spannable; +import android.text.style.URLSpan; +import android.text.util.Linkify; + +import com.todoroo.andlib.service.ContextManager; +import com.todoroo.astrid.api.AstridApiConstants; +import com.todoroo.astrid.api.TaskAction; +import com.todoroo.astrid.api.TaskDecoration; +import com.todoroo.astrid.data.Task; + +/** + * Exposes {@link TaskDecoration} for timers + * + * @author Tim Su + * + */ +public class LinkActionExposer extends BroadcastReceiver { + + private PackageManager pm; + + @Override + public void onReceive(Context context, Intent intent) { + ContextManager.setContext(context); + long taskId = intent.getLongExtra(AstridApiConstants.EXTRAS_TASK_ID, -1); + if(taskId == -1) + return; + + Task task = PluginServices.getTaskService().fetchById(taskId, Task.ID, Task.TITLE); + + Spannable titleSpan = Spannable.Factory.getInstance().newSpannable(task.getValue(Task.TITLE)); + Linkify.addLinks(titleSpan, Linkify.ALL); + + URLSpan[] urlSpans = titleSpan.getSpans(0, titleSpan.length(), URLSpan.class); + if(urlSpans.length == 0) + return; + + pm = context.getPackageManager(); + + for(URLSpan urlSpan : urlSpans) { + String url = urlSpan.getURL(); + int start = titleSpan.getSpanStart(urlSpan); + int end = titleSpan.getSpanEnd(urlSpan); + String text = titleSpan.subSequence(start, end).toString(); + sendLinkAction(context, taskId, url, text); + } + } + + private void sendLinkAction(Context context, long taskId, String url, String text) { + Intent itemIntent = new Intent(Intent.ACTION_VIEW); + itemIntent.setData(Uri.parse(url)); + List resolveInfoList = pm.queryIntentActivities(itemIntent, 0); + + Intent actionIntent; + + // if options > 1, display open with... + if(resolveInfoList.size() > 1) { + actionIntent = Intent.createChooser(itemIntent, text); + } + + // else show app that gets opened + else if(resolveInfoList.size() == 1) { + actionIntent = itemIntent; + } + + // no intents -> no item + else + return; + + Drawable icon = resolveInfoList.get(0).loadIcon(pm); + Bitmap bitmap = ((BitmapDrawable)icon).getBitmap(); + + TaskAction action = new TaskAction(text, + PendingIntent.getActivity(context, 0, actionIntent, 0), bitmap); + + // transmit + Intent broadcastIntent = new Intent(AstridApiConstants.BROADCAST_SEND_ACTIONS); + broadcastIntent.putExtra(AstridApiConstants.EXTRAS_ADDON, CorePlugin.IDENTIFIER); + broadcastIntent.putExtra(AstridApiConstants.EXTRAS_RESPONSE, action); + broadcastIntent.putExtra(AstridApiConstants.EXTRAS_TASK_ID, taskId); + context.sendBroadcast(broadcastIntent, AstridApiConstants.PERMISSION_READ); + } + +} diff --git a/astrid/src/com/todoroo/astrid/adapter/TaskAdapter.java b/astrid/src/com/todoroo/astrid/adapter/TaskAdapter.java index 6a53190bf..848b68041 100644 --- a/astrid/src/com/todoroo/astrid/adapter/TaskAdapter.java +++ b/astrid/src/com/todoroo/astrid/adapter/TaskAdapter.java @@ -19,6 +19,7 @@ import android.content.Context; import android.content.Intent; import android.content.res.Resources; import android.database.Cursor; +import android.graphics.Bitmap; import android.graphics.Paint; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; @@ -287,11 +288,6 @@ public class TaskAdapter extends CursorAdapter implements Filterable { if(hiddenUntil > DateUtilities.now()) nameValue = r.getString(R.string.TAd_hiddenFormat, nameValue); nameView.setText(nameValue); - - nameView.setMovementMethod(null); - if(nameValue.contains(".") || nameValue.contains("-")) //$NON-NLS-1$ //$NON-NLS-2$ - Linkify.addLinks(nameView, Linkify.EMAIL_ADDRESSES | Linkify.PHONE_NUMBERS | - Linkify.WEB_URLS); } // due date / completion date @@ -751,6 +747,7 @@ public class TaskAdapter extends CursorAdapter implements Filterable { if(mBar != null) { ListView listView = activity.getListView(); ViewHolder myHolder = null; + // update view if it is visible int length = listView.getChildCount(); for(int i = 0; i < length; i++) { @@ -766,8 +763,7 @@ public class TaskAdapter extends CursorAdapter implements Filterable { activity.runOnUiThread(new Runnable() { @Override public void run() { - Drawable drawable = new BitmapDrawable(activity.getResources(), item.icon); - mBarListener.addWithAction(new QuickAction(drawable, item.text), item); + mBarListener.addWithAction(item); mBar.show(viewHolder.view); } }); @@ -819,12 +815,20 @@ public class TaskAdapter extends CursorAdapter implements Filterable { new HashMap(2); private long taskId; private int itemCount = 0; + private int iconWidth; public void initialize(long newTaskId) { this.taskId = newTaskId; itemCount = 0; positionActionMap.clear(); mBar.setOnQuickActionClickListener(this); + iconWidth = activity.getResources().getDrawable(R.drawable.tango_edit).getIntrinsicHeight(); + } + + public void addWithAction(TaskAction item) { + Bitmap scaledBitmap = Bitmap.createScaledBitmap(item.icon, iconWidth, iconWidth, true); + Drawable drawable = new BitmapDrawable(activity.getResources(), scaledBitmap); + addWithAction(new QuickAction(drawable, item.text), item); } public void addWithAction(QuickAction quickAction, TaskAction taskAction) { @@ -859,7 +863,7 @@ public class TaskAdapter extends CursorAdapter implements Filterable { private class TaskRowListener implements OnCreateContextMenuListener, OnClickListener { - //prep quick action bar + // prepare quick action bar private void prepareQuickActionBar(ViewHolder viewHolder, Collection collection){ mBar = new QuickActionBar(viewHolder.view.getContext()); QuickAction editAction = new QuickAction(activity, R.drawable.tango_edit, @@ -869,8 +873,7 @@ public class TaskAdapter extends CursorAdapter implements Filterable { if(collection != null) { for(TaskAction item : collection) { - Drawable drawable = new BitmapDrawable(activity.getResources(), item.icon); - mBarListener.addWithAction(new QuickAction(drawable, item.text), item); + mBarListener.addWithAction(item); } } diff --git a/astrid/src/com/todoroo/astrid/helper/TaskAdapterAddOnManager.java b/astrid/src/com/todoroo/astrid/helper/TaskAdapterAddOnManager.java index 16b688cd5..df03ed983 100644 --- a/astrid/src/com/todoroo/astrid/helper/TaskAdapterAddOnManager.java +++ b/astrid/src/com/todoroo/astrid/helper/TaskAdapterAddOnManager.java @@ -3,6 +3,7 @@ */ package com.todoroo.astrid.helper; +import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; @@ -27,8 +28,8 @@ abstract public class TaskAdapterAddOnManager { this.activity = activity; } - private final Map> cache = - Collections.synchronizedMap(new HashMap>(0)); + private final Map> cache = + Collections.synchronizedMap(new HashMap>(0)); // --- interface @@ -107,7 +108,7 @@ abstract public class TaskAdapterAddOnManager { protected synchronized Collection initialize(long taskId) { if(cache.containsKey(taskId) && cache.get(taskId) != null) return get(taskId); - cache.put(taskId, new HashMap(0)); + cache.put(taskId, new ArrayList(0)); return null; } @@ -117,14 +118,15 @@ abstract public class TaskAdapterAddOnManager { * @param item * @return iterator if item was added, null if it already existed */ + @SuppressWarnings("unused") protected synchronized Collection addIfNotExists(long taskId, String addOn, TYPE item) { - HashMap list = cache.get(taskId); + ArrayList list = cache.get(taskId); if(list == null) return null; - if(list.containsKey(addOn) && list.get(addOn).equals(item)) + if(list.contains(item)) return null; - list.put(addOn, item); + list.add(item); return get(taskId); } @@ -136,7 +138,7 @@ abstract public class TaskAdapterAddOnManager { protected Collection get(long taskId) { if(cache.get(taskId) == null) return null; - return cache.get(taskId).values(); + return cache.get(taskId); } } \ No newline at end of file