package com.door43.util.tasks; import android.app.ProgressDialog; import android.content.Context; import android.content.DialogInterface; import android.os.Handler; import android.os.Looper; import android.util.Log; /** * This class performs a lot of the grunt work for handling managed tasks * The progress is displayed in a dialog */ public class GenericTaskWatcher implements ManagedTask.OnFinishedListener, ManagedTask.OnProgressListener, ManagedTask.OnStartListener, DialogInterface.OnCancelListener, ManagedTask.OnIdChangedListener { private final Context mContext; private final int mTitleRes; private final int mIconRes; private ProgressDialog mProgressDialog; private Object mTaskId; private boolean mWatching = false; private OnFinishedListener mOnFinishedListener; private OnCanceledListener mOnCanceledListener; /** * Create a new task handler * @param context * @param titleRes */ public GenericTaskWatcher(Context context, int titleRes) { mContext = context; mTitleRes = titleRes; mIconRes = 0; } /** * Create a new task handler * @param context * @param titleRes * @param iconRes */ public GenericTaskWatcher(Context context, int titleRes, int iconRes) { mContext = context; mTitleRes = titleRes; mIconRes = iconRes; } /** * Sets the listener to be fired when the task finishes * @param listener */ public void setOnFinishedListener(OnFinishedListener listener) { mOnFinishedListener = listener; } /** * Sets the listener to be fired when the task is canceled * If not set then the dialog will not be cancelable * @param listener */ public void setOnCanceledListener(OnCanceledListener listener) { mOnCanceledListener = listener; } /** * Checks if the task watcher is currently watching a task * @return */ public boolean isWatching() { return mWatching; } /** * Begin watching a task. * If you want to begin watching another task you should call disconnect() first * WARNING: this method expects the task with the given id to have already been added to the task manager * @param taskId */ public boolean watch(Object taskId) { if(!mWatching) { if(taskId != null) { ManagedTask task = TaskManager.getTask(taskId); return connectTask(task); } else { Log.w(null, "You cannot watch a task with id NULL"); return false; } } else { Log.w(null, "The watcher is already watching a task. Did you forget to call stop() first?"); return false; } } /** * Begin watching a task. * If you want to begin watching another task you should call disconnect() first * @param task */ public boolean watch(ManagedTask task) { if(!mWatching) { return connectTask(task); } else { Log.w(null, "The watcher is already watching a task. Did you forget to call stop() first?"); return false; } } private boolean connectTask(ManagedTask task) { if(task != null) { mWatching = true; // get task id task.addOnIdChangedListener(this); // task operation listeners task.addOnFinishedListener(this); task.addOnProgressListener(this); task.addOnStartListener(this); return true; } else { Log.w(null, "The task does not exist"); return false; } } /** * Disconnects the watcher from the task. * After closing you may begin watching another task */ public void stop() { if(mTaskId != null) { ManagedTask task = TaskManager.getTask(mTaskId); if(task != null) { task.removeOnIdChangedListener(this); task.removeOnFinishedListener(this); task.removeOnProgressListener(this); task.removeOnStartListener(this); } mTaskId = null; } if(mProgressDialog != null && mProgressDialog.isShowing()) { mProgressDialog.dismiss(); } mWatching = false; } @Override public void onFinished(final ManagedTask task) { TaskManager.clearTask(task); Handler hand = new Handler(Looper.getMainLooper()); hand.post(new Runnable() { @Override public void run() { if(mProgressDialog != null && mProgressDialog.isShowing()) { mProgressDialog.dismiss(); } if(mOnFinishedListener != null) { mOnFinishedListener.onFinished(task); } } }); } @Override public void onProgress(final ManagedTask task, final double progress, final String message, boolean secondary) { if(!task.isFinished()) { Handler hand = new Handler(Looper.getMainLooper()); hand.post(new Runnable() { @Override public void run() { if(task.isFinished()) { if(mProgressDialog != null) { mProgressDialog.dismiss(); } return; } if(mProgressDialog == null) { mProgressDialog = new ProgressDialog(mContext); mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); if(mOnCanceledListener != null) { mProgressDialog.setCancelable(true); mProgressDialog.setOnCancelListener(GenericTaskWatcher.this); } else { mProgressDialog.setCancelable(false); } mProgressDialog.setCanceledOnTouchOutside(false); mProgressDialog.setMax(task.maxProgress()); if(mIconRes != 0) { mProgressDialog.setIcon(mIconRes); } mProgressDialog.setTitle(mTitleRes); mProgressDialog.setMessage(""); } if(!mProgressDialog.isShowing()) { mProgressDialog.show(); } if(progress == -1) { mProgressDialog.setIndeterminate(true); mProgressDialog.setProgress(mProgressDialog.getMax()); } else { mProgressDialog.setIndeterminate(false); mProgressDialog.setProgress((int)Math.ceil(progress * mProgressDialog.getMax())); } if(!message.isEmpty()) { mProgressDialog.setMessage(message); } else { mProgressDialog.setMessage(""); } } }); } } @Override public void onStart(ManagedTask task) { // This is a stub. This isn't used anywhere yet } /** * The task dialog has been canceled * @param dialog */ @Override public void onCancel(DialogInterface dialog) { ManagedTask task = TaskManager.getTask(mTaskId); if(task != null) { TaskManager.cancelTask(task); TaskManager.clearTask(task); } mOnCanceledListener.onCanceled(task); } /** * The task id has been set * @param task */ @Override public void onChanged(ManagedTask task) { mTaskId = task.getTaskId(); } public interface OnCanceledListener { void onCanceled(ManagedTask task); } public interface OnFinishedListener { void onFinished(ManagedTask task); } }