summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--res/values/strings.xml1
-rw-r--r--src/de/danoeh/antennapod/asynctask/FlattrClickWorker.java375
-rw-r--r--src/de/danoeh/antennapod/storage/DBTasks.java2
-rw-r--r--src/de/danoeh/antennapod/storage/DBWriter.java4
4 files changed, 159 insertions, 223 deletions
diff --git a/res/values/strings.xml b/res/values/strings.xml
index adbd8f53f..d5725c6f3 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -165,6 +165,7 @@
<string name="return_home_label">Return to home</string>
<string name="flattr_auth_success">Authentication was successful! You can now flattr things within the app.</string>
<string name="no_flattr_token_title">No Flattr token found</string>
+ <string name="no_flattr_token_notification_msg">Your flattr account does not seem to be connected to AntennaPod. Tap here to authenticate.</string>
<string name="no_flattr_token_msg">Your flattr account does not seem to be connected to AntennaPod. You can either connect your account to AntennaPod to flattr things within the app or you can visit the website of the thing to flattr it there.</string>
<string name="authenticate_now_label">Authenticate</string>
<string name="action_forbidden_title">Action forbidden</string>
diff --git a/src/de/danoeh/antennapod/asynctask/FlattrClickWorker.java b/src/de/danoeh/antennapod/asynctask/FlattrClickWorker.java
index e9aa79ac1..06828944c 100644
--- a/src/de/danoeh/antennapod/asynctask/FlattrClickWorker.java
+++ b/src/de/danoeh/antennapod/asynctask/FlattrClickWorker.java
@@ -1,300 +1,235 @@
package de.danoeh.antennapod.asynctask;
-import android.annotation.SuppressLint;
+import android.annotation.TargetApi;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
-import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
-import android.net.ConnectivityManager;
-import android.net.NetworkInfo;
import android.os.AsyncTask;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import android.widget.Toast;
+
+import org.shredzone.flattr4j.exception.FlattrException;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+
import de.danoeh.antennapod.BuildConfig;
import de.danoeh.antennapod.R;
+import de.danoeh.antennapod.activity.FlattrAuthActivity;
import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.storage.DBReader;
import de.danoeh.antennapod.storage.DBWriter;
+import de.danoeh.antennapod.util.NetworkUtils;
import de.danoeh.antennapod.util.flattr.FlattrThing;
import de.danoeh.antennapod.util.flattr.FlattrUtils;
-import java.util.ArrayList;
-import java.util.List;
-
/**
* Performs a click action in a background thread.
+ * <p/>
+ * When started, the flattr click worker will try to flattr every item that is in the flattr queue. If no network
+ * connection is available it will shut down immediately. The FlattrClickWorker can also be given one additional
+ * FlattrThing which will be flattrd immediately.
+ * <p/>
+ * The FlattrClickWorker will display a toast notification for every item that has been flattrd. If the FlattrClickWorker failed
+ * to flattr something, a notification will be displayed.
*/
-
-public class FlattrClickWorker extends AsyncTask<Void, String, Void> {
+public class FlattrClickWorker extends AsyncTask<Void, Integer, FlattrClickWorker.ExitCode> {
protected static final String TAG = "FlattrClickWorker";
- protected Context context;
-
- private final int NOTIFICATION_ID = 4;
- protected String errorMsg;
- protected int exitCode;
- protected ArrayList<String> flattrd;
- protected ArrayList<String> flattr_failed;
+ private static final int NOTIFICATION_ID = 4;
+ private final Context context;
- protected NotificationCompat.Builder notificationCompatBuilder;
- private Notification.BigTextStyle notificationBuilder;
- protected NotificationManager notificationManager;
+ public static enum ExitCode {EXIT_NORMAL, NO_TOKEN, NO_NETWORK, NO_THINGS}
- protected ProgressDialog progDialog;
+ private volatile int countFailed = 0;
+ private volatile int countSuccess = 0;
- protected final static int EXIT_DEFAULT = 0;
- protected final static int NO_TOKEN = 1;
- protected final static int ENQUEUED = 2;
- protected final static int NO_THINGS = 3;
-
- public final static int ENQUEUE_ONLY = 1;
- public final static int FLATTR_TOAST = 2;
- public static final int FLATTR_NOTIFICATION = 3;
-
- private int run_mode = FLATTR_NOTIFICATION;
-
- private FlattrThing extra_flattr_thing; // additional urls to flattr that do *not* originate from the queue
+ private volatile FlattrThing extraFlattrThing;
/**
- * @param context
- * @param run_mode can be one of ENQUEUE_ONLY, FLATTR_TOAST and FLATTR_NOTIFICATION
+ * Only relevant if just one thing is flattrd
*/
- public FlattrClickWorker(Context context, int run_mode) {
- this(context);
- this.run_mode = run_mode;
- }
+ private volatile FlattrException exception;
+ /**
+ * Creates a new FlattrClickWorker which will only flattr all things in the queue.
+ * <p/>
+ * The FlattrClickWorker has to be started by calling executeAsync().
+ *
+ * @param context A context for accessing the database and posting notifications. Must not be null.
+ */
public FlattrClickWorker(Context context) {
- super();
- this.context = context;
- exitCode = EXIT_DEFAULT;
-
- flattrd = new ArrayList<String>();
- flattr_failed = new ArrayList<String>();
-
- errorMsg = "";
+ if (context == null) throw new IllegalArgumentException("context = null");
+ this.context = context.getApplicationContext();
}
- /* only used in PreferencesActivity for flattring antennapod itself,
- * can't really enqueue this thing
- */
- public FlattrClickWorker(Context context, FlattrThing thing) {
+ /**
+ * Creates a new FlattrClickWorker which will flattr all things in the queue and one additional
+ * FlattrThing.
+ * <p/>
+ * The FlattrClickWorker has to be started by calling executeAsync().
+ *
+ * @param context A context for accessing the database and posting notifications. Must not be null.
+ * @param extraFlattrThing The additional thing to flattr
+ */
+ public FlattrClickWorker(Context context, FlattrThing extraFlattrThing) {
this(context);
- extra_flattr_thing = thing;
- run_mode = FLATTR_TOAST;
- Log.d(TAG, "Going to flattr special thing that is not in the queue: " + thing.getTitle());
- }
-
- protected void onNoAccessToken() {
- Log.w(TAG, "No access token was available");
- }
-
- protected void onFlattrError() {
- FlattrUtils.showErrorDialog(context, errorMsg);
+ this.extraFlattrThing = extraFlattrThing;
}
- protected void onFlattred() {
- String notificationTitle = context.getString(R.string.flattrd_label);
- String notificationText = "", notificationSubText = "", notificationBigText = "";
-
- // text for successfully flattred items
- if (flattrd.size() == 1)
- notificationText = String.format(context.getString(R.string.flattr_click_success));
- else if (flattrd.size() > 1) // flattred pending items from queue
- notificationText = String.format(context.getString(R.string.flattr_click_success_count, flattrd.size()));
- if (flattrd.size() > 0) {
- String acc = "";
- for (String s : flattrd)
- acc += s + '\n';
- acc = acc.substring(0, acc.length() - 2);
+ @Override
+ protected ExitCode doInBackground(Void... params) {
- notificationBigText = String.format(context.getString(R.string.flattr_click_success_queue), acc);
+ if (!FlattrUtils.hasToken()) {
+ return ExitCode.NO_TOKEN;
}
- // add text for failures
- if (flattr_failed.size() > 0) {
- notificationTitle = context.getString(R.string.flattrd_failed_label);
- notificationText = String.format(context.getString(R.string.flattr_click_failure_count), flattr_failed.size())
- + " " + notificationText;
-
- notificationSubText = flattr_failed.get(0);
+ if (!NetworkUtils.networkAvailable(context)) {
+ return ExitCode.NO_NETWORK;
+ }
- String acc = "";
- for (String s : flattr_failed)
- acc += s + '\n';
- acc = acc.substring(0, acc.length() - 2);
+ final List<FlattrThing> flattrQueue = DBReader.getFlattrQueue(context);
+ if (extraFlattrThing != null) {
+ flattrQueue.add(extraFlattrThing);
+ } else if (flattrQueue.size() == 1) {
+ // if only one item is flattrd, the report can specifically mentioned that this item has failed
+ extraFlattrThing = flattrQueue.get(0);
+ }
- notificationBigText = String.format(context.getString(R.string.flattr_click_failure), acc)
- + "\n" + notificationBigText;
+ if (flattrQueue.isEmpty()) {
+ return ExitCode.NO_THINGS;
}
- Log.d(TAG, "Going to post notification: " + notificationBigText);
-
- notificationManager.cancel(NOTIFICATION_ID);
-
- if (run_mode == FLATTR_NOTIFICATION || flattr_failed.size() > 0) {
- PendingIntent contentIntent = PendingIntent.getActivity(context, 0, new Intent(context, MainActivity.class), 0);
- if (android.os.Build.VERSION.SDK_INT >= 16) {
- notificationBuilder = new Notification.BigTextStyle(
- new Notification.Builder(context)
- .setOngoing(false)
- .setContentTitle(notificationTitle)
- .setContentText(notificationText)
- .setContentIntent(contentIntent)
- .setSubText(notificationSubText)
- .setSmallIcon(R.drawable.stat_notify_sync))
- .bigText(notificationText + "\n" + notificationBigText);
- notificationManager.notify(NOTIFICATION_ID, notificationBuilder.build());
- } else {
- notificationCompatBuilder = new NotificationCompat.Builder(context) // need new notificationBuilder and cancel/renotify to get rid of progress bar
- .setContentTitle(notificationTitle)
- .setContentText(notificationText)
- .setContentIntent(contentIntent)
- .setSubText(notificationBigText)
- .setTicker(notificationTitle)
- .setSmallIcon(R.drawable.stat_notify_sync)
- .setOngoing(false);
- notificationManager.notify(NOTIFICATION_ID, notificationCompatBuilder.build());
+ List<Future> dbFutures = new LinkedList<Future>();
+ for (FlattrThing thing : flattrQueue) {
+ if (BuildConfig.DEBUG) Log.d(TAG, "Processing " + thing.getTitle());
+
+ try {
+ thing.getFlattrStatus().setUnflattred(); // pop from queue to prevent unflattrable things from getting stuck in flattr queue infinitely
+ FlattrUtils.clickUrl(context, thing.getPaymentLink());
+ thing.getFlattrStatus().setFlattred();
+ publishProgress(R.string.flattr_click_success);
+ countSuccess++;
+
+ } catch (FlattrException e) {
+ e.printStackTrace();
+ countFailed++;
+ if (countFailed == 1) {
+ exception = e;
+ }
}
- } else if (run_mode == FLATTR_TOAST) {
- Toast.makeText(context.getApplicationContext(),
- notificationText,
- Toast.LENGTH_LONG)
- .show();
- }
- }
- protected void onEnqueue() {
- Toast.makeText(context.getApplicationContext(),
- R.string.flattr_click_enqueued,
- Toast.LENGTH_LONG)
- .show();
- }
+ Future<?> f = DBWriter.setFlattredStatus(context, thing, false);
+ if (f != null) {
+ dbFutures.add(f);
+ }
+ }
- protected void onSetupNotification() {
- if (android.os.Build.VERSION.SDK_INT >= 16) {
- notificationBuilder = new Notification.BigTextStyle(
- new Notification.Builder(context)
- .setContentTitle(context.getString(R.string.flattring_label))
- .setAutoCancel(true)
- .setSmallIcon(R.drawable.stat_notify_sync)
- .setProgress(0, 0, true)
- .setOngoing(true));
- } else {
- notificationCompatBuilder = new NotificationCompat.Builder(context)
- .setContentTitle(context.getString(R.string.flattring_label))
- .setAutoCancel(true)
- .setSmallIcon(R.drawable.stat_notify_sync)
- .setProgress(0, 0, true)
- .setOngoing(true);
+ for (Future f : dbFutures) {
+ try {
+ f.get();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ } catch (ExecutionException e) {
+ e.printStackTrace();
+ }
}
- notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
+ return ExitCode.EXIT_NORMAL;
}
@Override
- protected void onPostExecute(Void result) {
- if (BuildConfig.DEBUG) Log.d(TAG, "Exit code was " + exitCode);
-
+ protected void onPostExecute(ExitCode exitCode) {
+ super.onPostExecute(exitCode);
switch (exitCode) {
- case NO_TOKEN:
- notificationManager.cancel(NOTIFICATION_ID);
- onNoAccessToken();
+ case EXIT_NORMAL:
+ if (countFailed > 0) {
+ postFlattrFailedNotification();
+ }
break;
- case ENQUEUED:
- onEnqueue();
+ case NO_NETWORK:
+ postToastNotification(R.string.flattr_click_enqueued);
break;
- case EXIT_DEFAULT:
- onFlattred();
+ case NO_TOKEN:
+ postNoTokenNotification();
break;
- case NO_THINGS: // FlattrClickWorker called automatically somewhere to empty flattr queue
- notificationManager.cancel(NOTIFICATION_ID);
+ case NO_THINGS: // nothing to notify here
break;
}
}
@Override
- protected void onPreExecute() {
- onSetupNotification();
+ protected void onProgressUpdate(Integer... values) {
+ super.onProgressUpdate(values);
+ postToastNotification(values[0]);
}
- private static boolean haveInternetAccess(Context context) {
- ConnectivityManager cm =
- (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
-
- NetworkInfo networkInfo = cm.getActiveNetworkInfo();
- return (networkInfo != null && networkInfo.isConnectedOrConnecting());
+ private void postToastNotification(int msg) {
+ Toast.makeText(context, context.getString(msg), Toast.LENGTH_LONG).show();
}
- @Override
- protected Void doInBackground(Void... params) {
- if (BuildConfig.DEBUG) Log.d(TAG, "Starting background work");
-
- exitCode = EXIT_DEFAULT;
-
- if (!FlattrUtils.hasToken()) {
- exitCode = NO_TOKEN;
- } else if (DBReader.getFlattrQueueEmpty(context) && extra_flattr_thing == null) {
- exitCode = NO_THINGS;
- } else if (!haveInternetAccess(context) || run_mode == ENQUEUE_ONLY) {
- exitCode = ENQUEUED;
- } else {
- List<FlattrThing> flattrList = DBReader.getFlattrQueue(context);
- Log.d(TAG, "flattrQueue processing list with " + flattrList.size() + " items.");
-
- if (extra_flattr_thing != null)
- flattrList.add(extra_flattr_thing);
-
- flattrd.ensureCapacity(flattrList.size());
-
- for (FlattrThing thing : flattrList) {
- try {
- Log.d(TAG, "flattrQueue processing " + thing.getTitle() + " " + thing.getPaymentLink());
- publishProgress(String.format(context.getString(R.string.flattring_thing), thing.getTitle()));
-
- thing.getFlattrStatus().setUnflattred(); // pop from queue to prevent unflattrable things from getting stuck in flattr queue infinitely
-
- FlattrUtils.clickUrl(context, thing.getPaymentLink());
- flattrd.add(thing.getTitle());
-
- thing.getFlattrStatus().setFlattred();
- } catch (Exception e) {
- Log.d(TAG, "flattrQueue processing exception at item " + thing.getTitle() + " " + e.getMessage());
- flattr_failed.ensureCapacity(flattrList.size());
- flattr_failed.add(thing.getTitle() + ": " + e.getMessage());
- }
- Log.d(TAG, "flattrQueue processing - going to write thing back to db with flattr_status " + Long.toString(thing.getFlattrStatus().toLong()));
- DBWriter.setFlattredStatus(context, thing, false);
- }
+ private void postNoTokenNotification() {
+ PendingIntent contentIntent = PendingIntent.getActivity(context, 0, new Intent(context, FlattrAuthActivity.class), 0);
+
+ Notification notification = new NotificationCompat.Builder(context)
+ .setStyle(new NotificationCompat.BigTextStyle().bigText(context.getString(R.string.no_flattr_token_notification_msg)))
+ .setContentIntent(contentIntent)
+ .setContentTitle(context.getString(R.string.no_flattr_token_title))
+ .setTicker(context.getString(R.string.no_flattr_token_title))
+ .setSmallIcon(R.drawable.stat_notify_sync_error)
+ .setOngoing(false)
+ .setAutoCancel(true)
+ .build();
+ ((NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE)).notify(NOTIFICATION_ID, notification);
+ }
+ private void postFlattrFailedNotification() {
+ if (countFailed == 0) {
+ return;
}
- return null;
- }
-
- @Override
- protected void onProgressUpdate(String... names) {
PendingIntent contentIntent = PendingIntent.getActivity(context, 0, new Intent(context, MainActivity.class), 0);
- if (android.os.Build.VERSION.SDK_INT >= 16) {
- notificationBuilder.setBigContentTitle(names[0]);
- notificationManager.notify(NOTIFICATION_ID, notificationBuilder.build());
+ String title;
+ String subtext;
+
+ if (countFailed == 1) {
+ title = context.getString(R.string.flattrd_failed_label);
+ String exceptionMsg = (exception.getMessage() != null) ? exception.getMessage() : "";
+ subtext = context.getString(R.string.flattr_click_failure, extraFlattrThing.getTitle())
+ + "\n" + exceptionMsg;
} else {
- notificationCompatBuilder.setContentText(names[0]);
- notificationCompatBuilder.setContentIntent(contentIntent);
- notificationManager.notify(NOTIFICATION_ID, notificationCompatBuilder.build());
+ title = context.getString(R.string.flattrd_label);
+ subtext = context.getString(R.string.flattr_click_success_count, countSuccess) + "\n"
+ + context.getString(R.string.flattr_click_failure_count, countFailed);
}
+
+ Notification notification = new NotificationCompat.Builder(context)
+ .setStyle(new NotificationCompat.BigTextStyle().bigText(subtext))
+ .setContentIntent(contentIntent)
+ .setContentTitle(title)
+ .setTicker(title)
+ .setSmallIcon(R.drawable.stat_notify_sync_error)
+ .setOngoing(false)
+ .setAutoCancel(true)
+ .build();
+ ((NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE)).notify(NOTIFICATION_ID, notification);
}
- @SuppressLint("NewApi")
+
+ /**
+ * Starts the FlattrClickWorker as an AsyncTask.
+ */
+ @TargetApi(11)
public void executeAsync() {
- FlattrUtils.hasToken();
if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.GINGERBREAD_MR1) {
- executeOnExecutor(THREAD_POOL_EXECUTOR);
+ executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} else {
execute();
}
diff --git a/src/de/danoeh/antennapod/storage/DBTasks.java b/src/de/danoeh/antennapod/storage/DBTasks.java
index c6a34aeea..7e87b938a 100644
--- a/src/de/danoeh/antennapod/storage/DBTasks.java
+++ b/src/de/danoeh/antennapod/storage/DBTasks.java
@@ -156,7 +156,7 @@ public final class DBTasks {
if (FlattrUtils.hasToken()) {
if (BuildConfig.DEBUG) Log.d(TAG, "Flattring all pending things.");
- new FlattrClickWorker(context, FlattrClickWorker.FLATTR_NOTIFICATION).executeAsync(); // flattr pending things
+ new FlattrClickWorker(context).executeAsync(); // flattr pending things
if (BuildConfig.DEBUG) Log.d(TAG, "Fetching flattr status.");
new FlattrStatusFetcher(context).start();
diff --git a/src/de/danoeh/antennapod/storage/DBWriter.java b/src/de/danoeh/antennapod/storage/DBWriter.java
index ffdfc65fd..9916ac97f 100644
--- a/src/de/danoeh/antennapod/storage/DBWriter.java
+++ b/src/de/danoeh/antennapod/storage/DBWriter.java
@@ -868,7 +868,7 @@ public class DBWriter {
adapter.setFeedItemFlattrStatus(item);
adapter.close();
if (startFlattrClickWorker) {
- new FlattrClickWorker(context, FlattrClickWorker.FLATTR_TOAST).executeAsync();
+ new FlattrClickWorker(context).executeAsync();
}
}
});
@@ -891,7 +891,7 @@ public class DBWriter {
adapter.setFeedFlattrStatus(feed);
adapter.close();
if (startFlattrClickWorker) {
- new FlattrClickWorker(context, FlattrClickWorker.FLATTR_TOAST).executeAsync();
+ new FlattrClickWorker(context).executeAsync();
}
}
});