summaryrefslogtreecommitdiff
path: root/src/de/danoeh/antennapod/util
diff options
context:
space:
mode:
Diffstat (limited to 'src/de/danoeh/antennapod/util')
-rw-r--r--src/de/danoeh/antennapod/util/ConnectionTester.java66
-rw-r--r--src/de/danoeh/antennapod/util/Converter.java81
-rw-r--r--src/de/danoeh/antennapod/util/DownloadError.java42
-rw-r--r--src/de/danoeh/antennapod/util/FeedItemMenuHandler.java120
-rw-r--r--src/de/danoeh/antennapod/util/FeedItemPubdateComparator.java19
-rw-r--r--src/de/danoeh/antennapod/util/FeedMenuHandler.java84
-rw-r--r--src/de/danoeh/antennapod/util/FeedtitleComparator.java15
-rw-r--r--src/de/danoeh/antennapod/util/FlattrUtils.java215
-rw-r--r--src/de/danoeh/antennapod/util/MediaPlayerError.java23
-rw-r--r--src/de/danoeh/antennapod/util/NumberGenerator.java25
-rw-r--r--src/de/danoeh/antennapod/util/ShareUtils.java34
-rw-r--r--src/de/danoeh/antennapod/util/StorageUtils.java28
-rw-r--r--src/de/danoeh/antennapod/util/URLChecker.java39
13 files changed, 791 insertions, 0 deletions
diff --git a/src/de/danoeh/antennapod/util/ConnectionTester.java b/src/de/danoeh/antennapod/util/ConnectionTester.java
new file mode 100644
index 000000000..d50e63f00
--- /dev/null
+++ b/src/de/danoeh/antennapod/util/ConnectionTester.java
@@ -0,0 +1,66 @@
+package de.danoeh.antennapod.util;
+
+import java.io.IOException;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLConnection;
+
+import android.content.Context;
+import android.util.Log;
+
+/** Tests a connection before downloading something. */
+public class ConnectionTester implements Runnable {
+ private static final String TAG = "ConnectionTester";
+ private String strUrl;
+ private Context context;
+ private int connectTimeout;
+ private int readTimeout;
+ private Callback callback;
+ private int reason;
+
+ public ConnectionTester(String url, Context context, Callback callback) {
+ super();
+ this.strUrl = url;
+ this.context = context;
+ this.callback = callback;
+ connectTimeout = 500;
+ readTimeout = connectTimeout;
+ }
+
+
+
+ @Override
+ public void run() {
+ Log.d(TAG, "Testing connection");
+ try {
+ URL url = new URL(strUrl);
+ HttpURLConnection con = (HttpURLConnection) url.openConnection();
+ con.connect();
+ callback.onConnectionSuccessful();
+ Log.d(TAG, "Connection seems to work");
+ } catch (MalformedURLException e) {
+ e.printStackTrace();
+ reason = DownloadError.ERROR_CONNECTION_ERROR;
+ Log.d(TAG, "Connection failed");
+ callback.onConnectionFailure();
+ } catch (IOException e) {
+ e.printStackTrace();
+ reason = DownloadError.ERROR_CONNECTION_ERROR;
+ Log.d(TAG, "Connection failed");
+ callback.onConnectionFailure();
+ }
+ }
+
+
+ public static abstract class Callback {
+ public abstract void onConnectionSuccessful();
+ public abstract void onConnectionFailure();
+ }
+
+ public int getReason() {
+ return reason;
+ }
+
+
+}
diff --git a/src/de/danoeh/antennapod/util/Converter.java b/src/de/danoeh/antennapod/util/Converter.java
new file mode 100644
index 000000000..f02e8ea69
--- /dev/null
+++ b/src/de/danoeh/antennapod/util/Converter.java
@@ -0,0 +1,81 @@
+package de.danoeh.antennapod.util;
+
+import android.util.Log;
+
+/** Provides methods for converting various units. */
+public final class Converter {
+ /** Class shall not be instantiated. */
+ private Converter() {
+ }
+
+ /** Logging tag. */
+ private static final String TAG = "Converter";
+
+
+ /** Indicates that the value is in the Byte range.*/
+ private static final int B_RANGE = 0;
+ /** Indicates that the value is in the Kilobyte range.*/
+ private static final int KB_RANGE = 1;
+ /** Indicates that the value is in the Megabyte range.*/
+ private static final int MB_RANGE = 2;
+ /** Indicates that the value is in the Gigabyte range.*/
+ private static final int GB_RANGE = 3;
+ /** Determines the length of the number for best readability.*/
+ private static final int NUM_LENGTH = 1000;
+
+
+ private static final int HOURS_MIL = 3600000;
+ private static final int MINUTES_MIL = 60000;
+ private static final int SECONDS_MIL = 1000;
+
+ /** Takes a byte-value and converts it into a more readable
+ * String.
+ * @param input The value to convert
+ * @return The converted String with a unit
+ * */
+ public static String byteToString(final long input) {
+ int i = 0;
+ int result = 0;
+
+ for (i = 0; i < GB_RANGE + 1; i++) {
+ result = (int) (input / Math.pow(1024, i));
+ if (result < NUM_LENGTH) {
+ break;
+ }
+ }
+
+ switch (i) {
+ case B_RANGE:
+ return result + " B";
+ case KB_RANGE:
+ return result + " KB";
+ case MB_RANGE:
+ return result + " MB";
+ case GB_RANGE:
+ return result + " GB";
+ default:
+ Log.e(TAG, "Error happened in byteToString");
+ return "ERROR";
+ }
+ }
+
+ /** Converts milliseconds to a string containing hours, minutes and seconds */
+ public static String getDurationStringLong(int duration) {
+ int h = duration / HOURS_MIL;
+ int rest = duration - h * HOURS_MIL;
+ int m = rest / MINUTES_MIL;
+ rest -= m * MINUTES_MIL;
+ int s = rest / SECONDS_MIL;
+
+ return String.format("%02d:%02d:%02d", h, m, s);
+ }
+
+ /** Converts milliseconds to a string containing hours and minutes */
+ public static String getDurationStringShort(int duration) {
+ int h = duration / HOURS_MIL;
+ int rest = duration - h * HOURS_MIL;
+ int m = rest / MINUTES_MIL;
+
+ return String.format("%02d:%02d", h, m);
+ }
+}
diff --git a/src/de/danoeh/antennapod/util/DownloadError.java b/src/de/danoeh/antennapod/util/DownloadError.java
new file mode 100644
index 000000000..b2f43a8dd
--- /dev/null
+++ b/src/de/danoeh/antennapod/util/DownloadError.java
@@ -0,0 +1,42 @@
+package de.danoeh.antennapod.util;
+
+import de.danoeh.antennapod.R;
+import android.app.DownloadManager;
+import android.content.Context;
+
+/** Utility class for Download Errors. */
+public class DownloadError {
+ public static final int ERROR_PARSER_EXCEPTION = 1;
+ public static final int ERROR_UNSUPPORTED_TYPE = 2;
+ public static final int ERROR_CONNECTION_ERROR = 3;
+
+
+ /** Get a human-readable string for a specific error code. */
+ public static String getErrorString(Context context, int code) {
+ int resId;
+ switch(code) {
+ case DownloadManager.ERROR_DEVICE_NOT_FOUND:
+ resId = R.string.download_error_insufficient_space;
+ break;
+ case DownloadManager.ERROR_FILE_ERROR:
+ resId = R.string.download_error_file_error;
+ break;
+ case DownloadManager.ERROR_HTTP_DATA_ERROR:
+ resId = R.string.download_error_http_data_error;
+ break;
+ case ERROR_PARSER_EXCEPTION:
+ resId = R.string.download_error_parser_exception;
+ break;
+ case ERROR_UNSUPPORTED_TYPE:
+ resId = R.string.download_error_unsupported_type;
+ break;
+ case ERROR_CONNECTION_ERROR:
+ resId = R.string.download_error_connection_error;
+ break;
+ default:
+ resId = R.string.download_error_error_unknown;
+ }
+ return context.getString(resId);
+ }
+
+}
diff --git a/src/de/danoeh/antennapod/util/FeedItemMenuHandler.java b/src/de/danoeh/antennapod/util/FeedItemMenuHandler.java
new file mode 100644
index 000000000..b97bf35b3
--- /dev/null
+++ b/src/de/danoeh/antennapod/util/FeedItemMenuHandler.java
@@ -0,0 +1,120 @@
+package de.danoeh.antennapod.util;
+
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+
+import com.actionbarsherlock.view.Menu;
+import com.actionbarsherlock.view.MenuInflater;
+import com.actionbarsherlock.view.MenuItem;
+
+import de.danoeh.antennapod.feed.FeedItem;
+import de.danoeh.antennapod.feed.FeedManager;
+import de.danoeh.antennapod.storage.DownloadRequester;
+import de.danoeh.antennapod.R;
+
+/** Handles interactions with the FeedItemMenu. */
+public class FeedItemMenuHandler {
+ private FeedItemMenuHandler() {
+
+ }
+
+ public static boolean onPrepareMenu(Menu menu, FeedItem selectedItem) {
+ FeedManager manager = FeedManager.getInstance();
+
+ if (selectedItem.getMedia() != null) {
+ if (selectedItem.getMedia().isDownloaded()) {
+ menu.findItem(R.id.play_item).setVisible(true);
+ menu.findItem(R.id.remove_item).setVisible(true);
+ } else if (selectedItem.getMedia().getFile_url() == null) {
+ menu.findItem(R.id.download_item).setVisible(true);
+ menu.findItem(R.id.stream_item).setVisible(true);
+ } else {
+ menu.findItem(R.id.cancel_download_item).setVisible(true);
+ }
+
+ if (manager.isInQueue(selectedItem)) {
+ menu.findItem(R.id.remove_from_queue_item).setVisible(true);
+ } else {
+ menu.findItem(R.id.add_to_queue_item).setVisible(true);
+ }
+
+ menu.findItem(R.id.share_link_item).setVisible(selectedItem.getLink() != null);
+ }
+
+ if (selectedItem.isRead()) {
+ menu.findItem(R.id.mark_unread_item).setVisible(true);
+ } else {
+ menu.findItem(R.id.mark_read_item).setVisible(true);
+ }
+
+ if (selectedItem.getLink() != null) {
+ menu.findItem(R.id.visit_website_item).setVisible(true);
+ }
+
+ if (selectedItem.getPaymentLink() != null) {
+ menu.findItem(R.id.support_item).setVisible(true);
+ }
+
+ return true;
+ }
+
+ public static boolean onMenuItemClicked(Context context, MenuItem item,
+ FeedItem selectedItem) {
+ DownloadRequester requester = DownloadRequester.getInstance();
+ FeedManager manager = FeedManager.getInstance();
+ switch (item.getItemId()) {
+ case R.id.download_item:
+ requester.downloadMedia(context, selectedItem.getMedia());
+ break;
+ case R.id.play_item:
+ manager.playMedia(context, selectedItem.getMedia(), true, true,
+ false);
+ break;
+ case R.id.remove_item:
+ manager.deleteFeedMedia(context, selectedItem.getMedia());
+ break;
+ case R.id.cancel_download_item:
+ requester.cancelDownload(context, selectedItem.getMedia()
+ .getDownloadId());
+ break;
+ case R.id.mark_read_item:
+ manager.markItemRead(context, selectedItem, true);
+ break;
+ case R.id.mark_unread_item:
+ manager.markItemRead(context, selectedItem, false);
+ break;
+ case R.id.add_to_queue_item:
+ manager.addQueueItem(context, selectedItem);
+ break;
+ case R.id.remove_from_queue_item:
+ manager.removeQueueItem(context, selectedItem);
+ break;
+ case R.id.stream_item:
+ manager.playMedia(context, selectedItem.getMedia(), true, true,
+ true);
+ break;
+ case R.id.visit_website_item:
+ Uri uri = Uri.parse(selectedItem.getLink());
+ context.startActivity(new Intent(Intent.ACTION_VIEW, uri));
+ break;
+ case R.id.support_item:
+ FlattrUtils.clickUrl(context, selectedItem.getPaymentLink());
+ break;
+ case R.id.share_link_item:
+ ShareUtils.shareFeedItemLink(context, selectedItem);
+ break;
+ default:
+ return false;
+ }
+ // Refresh menu state
+
+ return true;
+ }
+
+ public static boolean onCreateMenu(MenuInflater inflater, Menu menu) {
+ inflater.inflate(R.menu.feeditem, menu);
+ return true;
+ }
+
+}
diff --git a/src/de/danoeh/antennapod/util/FeedItemPubdateComparator.java b/src/de/danoeh/antennapod/util/FeedItemPubdateComparator.java
new file mode 100644
index 000000000..bfeaf59e8
--- /dev/null
+++ b/src/de/danoeh/antennapod/util/FeedItemPubdateComparator.java
@@ -0,0 +1,19 @@
+package de.danoeh.antennapod.util;
+
+import java.util.Comparator;
+
+import de.danoeh.antennapod.feed.FeedItem;
+
+/** Compares the pubDate of two FeedItems for sorting*/
+public class FeedItemPubdateComparator implements Comparator<FeedItem> {
+
+ /** Returns a new instance of this comparator in reverse order.
+ public static FeedItemPubdateComparator newInstance() {
+ FeedItemPubdateComparator
+ }*/
+ @Override
+ public int compare(FeedItem lhs, FeedItem rhs) {
+ return -lhs.getPubDate().compareTo(rhs.getPubDate());
+ }
+
+}
diff --git a/src/de/danoeh/antennapod/util/FeedMenuHandler.java b/src/de/danoeh/antennapod/util/FeedMenuHandler.java
new file mode 100644
index 000000000..10afc687c
--- /dev/null
+++ b/src/de/danoeh/antennapod/util/FeedMenuHandler.java
@@ -0,0 +1,84 @@
+package de.danoeh.antennapod.util;
+
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.util.Log;
+
+import com.actionbarsherlock.view.ActionMode;
+import com.actionbarsherlock.view.Menu;
+import com.actionbarsherlock.view.MenuInflater;
+import com.actionbarsherlock.view.MenuItem;
+
+import de.danoeh.antennapod.activity.FeedInfoActivity;
+import de.danoeh.antennapod.feed.Feed;
+import de.danoeh.antennapod.feed.FeedItem;
+import de.danoeh.antennapod.feed.FeedManager;
+import de.danoeh.antennapod.service.DownloadService;
+import de.danoeh.antennapod.storage.DownloadRequester;
+import de.danoeh.antennapod.R;
+
+/** Handles interactions with the FeedItemMenu. */
+public class FeedMenuHandler {
+ private static final String TAG = "FeedMenuHandler";
+
+ public static boolean onCreateOptionsMenu(MenuInflater inflater, Menu menu) {
+ inflater.inflate(R.menu.feedlist, menu);
+ return true;
+ }
+
+ public static boolean onPrepareOptionsMenu(Menu menu, Feed selectedFeed) {
+ Log.d(TAG, "Preparing options menu");
+ if (selectedFeed.getPaymentLink() != null) {
+ menu.findItem(R.id.support_item).setVisible(true);
+ }
+ MenuItem refresh = menu.findItem(R.id.refresh_item);
+ if (DownloadService.isRunning
+ && DownloadRequester.getInstance().isDownloadingFile(
+ selectedFeed)) {
+ refresh.setVisible(false);
+ } else {
+ refresh.setVisible(true);
+ }
+
+ menu.findItem(R.id.share_link_item).setVisible(selectedFeed.getLink() != null);
+
+ return true;
+ }
+
+ /** NOTE: This method does not handle clicks on the 'remove feed' - item. */
+ public static boolean onOptionsItemClicked(Context context, MenuItem item,
+ Feed selectedFeed) {
+ FeedManager manager = FeedManager.getInstance();
+ switch (item.getItemId()) {
+ case R.id.show_info_item:
+ Intent startIntent = new Intent(context, FeedInfoActivity.class);
+ startIntent.putExtra(FeedInfoActivity.EXTRA_FEED_ID,
+ selectedFeed.getId());
+ context.startActivity(startIntent);
+ break;
+ case R.id.refresh_item:
+ manager.refreshFeed(context, selectedFeed);
+ break;
+ case R.id.mark_all_read_item:
+ manager.markFeedRead(context, selectedFeed);
+ break;
+ case R.id.visit_website_item:
+ Uri uri = Uri.parse(selectedFeed.getLink());
+ context.startActivity(new Intent(Intent.ACTION_VIEW, uri));
+ break;
+ case R.id.support_item:
+ FlattrUtils.clickUrl(context, selectedFeed.getPaymentLink());
+ break;
+ case R.id.share_link_item:
+ ShareUtils.shareFeedlink(context, selectedFeed);
+ break;
+ case R.id.share_source_item:
+ ShareUtils.shareFeedDownloadLink(context, selectedFeed);
+ break;
+ default:
+ return false;
+ }
+ return true;
+ }
+}
diff --git a/src/de/danoeh/antennapod/util/FeedtitleComparator.java b/src/de/danoeh/antennapod/util/FeedtitleComparator.java
new file mode 100644
index 000000000..39a258b62
--- /dev/null
+++ b/src/de/danoeh/antennapod/util/FeedtitleComparator.java
@@ -0,0 +1,15 @@
+package de.danoeh.antennapod.util;
+
+import java.util.Comparator;
+
+import de.danoeh.antennapod.feed.Feed;
+
+/** Compares the title of two feeds for sorting. */
+public class FeedtitleComparator implements Comparator<Feed> {
+
+ @Override
+ public int compare(Feed lhs, Feed rhs) {
+ return lhs.getTitle().compareTo(rhs.getTitle());
+ }
+
+}
diff --git a/src/de/danoeh/antennapod/util/FlattrUtils.java b/src/de/danoeh/antennapod/util/FlattrUtils.java
new file mode 100644
index 000000000..b8f1d02bc
--- /dev/null
+++ b/src/de/danoeh/antennapod/util/FlattrUtils.java
@@ -0,0 +1,215 @@
+package de.danoeh.antennapod.util;
+
+import java.util.EnumSet;
+
+import org.shredzone.flattr4j.FlattrFactory;
+import org.shredzone.flattr4j.FlattrService;
+import org.shredzone.flattr4j.exception.FlattrException;
+import org.shredzone.flattr4j.oauth.AccessToken;
+import org.shredzone.flattr4j.oauth.AndroidAuthenticator;
+import org.shredzone.flattr4j.oauth.Scope;
+
+import android.app.AlertDialog;
+import android.app.AlertDialog.Builder;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnClickListener;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.net.Uri;
+import android.preference.PreferenceManager;
+import android.util.Log;
+import android.widget.Toast;
+import de.danoeh.antennapod.PodcastApp;
+import de.danoeh.antennapod.activity.FlattrAuthActivity;
+import de.danoeh.antennapod.R;
+
+/** Utility methods for doing something with flattr. */
+public class FlattrUtils {
+ private static final String TAG = "FlattrUtils";
+
+ private static final String HOST_NAME = "de.danoeh.antennapod";
+ private static final String APP_KEY = "qBoVa9rhUOSPCrBwYPjzyNytHRbkPul5VzRWz93jNMZf4rCS7LhwpGPWnR73biZW";
+ private static final String APP_SECRET = "IGJ8FDiif7n9pPSmr0JHwotK5rD7AsU8Yt7uWfC2cQ2svKFNAekXtExpV1mlk7k8";
+
+ private static final String PREF_ACCESS_TOKEN = "de.danoeh.antennapod.preference.flattrAccessToken";
+
+ private static AndroidAuthenticator createAuthenticator() {
+ return new AndroidAuthenticator(HOST_NAME, APP_KEY, APP_SECRET);
+ }
+
+ public static void startAuthProcess(Context context) throws FlattrException {
+ AndroidAuthenticator auth = createAuthenticator();
+ auth.setScope(EnumSet.of(Scope.FLATTR));
+ Intent intent = auth.createAuthenticateIntent();
+ context.startActivity(intent);
+ }
+
+ /**
+ * Returns the access token from the preferences or null if no access token
+ * was saved before.
+ */
+ public static AccessToken retrieveToken() {
+ Log.d(TAG, "Retrieving access token");
+ String token = PreferenceManager.getDefaultSharedPreferences(
+ PodcastApp.getInstance()).getString(PREF_ACCESS_TOKEN, null);
+ if (token != null) {
+ Log.d(TAG, "Found access token");
+ return new AccessToken(token);
+ } else {
+ Log.d(TAG, "No access token found");
+ return null;
+ }
+ }
+
+ /** Returns true if the application has saved an access token */
+ public static boolean hasToken() {
+ return retrieveToken() != null;
+ }
+
+ /** Stores the token as a preference */
+ private static void storeToken(AccessToken token) {
+ Log.d(TAG, "Storing token");
+ SharedPreferences.Editor editor = PreferenceManager
+ .getDefaultSharedPreferences(PodcastApp.getInstance()).edit();
+ if (token != null) {
+ editor.putString(PREF_ACCESS_TOKEN, token.getToken());
+ } else {
+ editor.putString(PREF_ACCESS_TOKEN, null);
+ }
+ editor.commit();
+ }
+
+ public static void deleteToken() {
+ Log.d(TAG, "Deleting flattr token");
+ storeToken(null);
+ }
+
+ public static void clickUrl(Context context, String url) {
+ FlattrFactory factory = FlattrFactory.getInstance();
+ AccessToken token = retrieveToken();
+ if (token != null) {
+ FlattrService fs = factory.createFlattrService(retrieveToken());
+ try {
+ fs.click(url);
+ Toast toast = Toast.makeText(context.getApplicationContext(),
+ R.string.flattr_click_success, Toast.LENGTH_LONG);
+ toast.show();
+ } catch (FlattrException e) {
+ e.printStackTrace();
+ showErrorDialog(context, e.getMessage());
+ }
+ } else {
+ showNoTokenDialog(context, url);
+ }
+ }
+
+ public static AccessToken handleCallback(Uri uri) throws FlattrException {
+ AndroidAuthenticator auth = createAuthenticator();
+ AccessToken token = auth.fetchAccessToken(uri);
+ if (token != null) {
+ Log.d(TAG, "Successfully got token");
+ storeToken(token);
+ return token;
+ } else {
+ Log.w(TAG, "Flattr token was null");
+ return null;
+ }
+ }
+
+ public static void revokeAccessToken(Context context) {
+ Log.d(TAG, "Revoking access token");
+ deleteToken();
+ showRevokeDialog(context);
+ }
+
+
+ //------------------------------------------------ DIALOGS
+
+ private static void showRevokeDialog(final Context context) {
+ AlertDialog.Builder builder = new AlertDialog.Builder(context);
+ builder.setTitle(R.string.access_revoked_title);
+ builder.setMessage(R.string.access_revoked_info);
+ builder.setNeutralButton(android.R.string.ok, new OnClickListener() {
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ dialog.cancel();
+ }
+ });
+ builder.create().show();
+ }
+
+ private static void showNoTokenDialog(final Context context,
+ final String url) {
+ Log.d(TAG, "Creating showNoTokenDialog");
+ AlertDialog.Builder builder = new AlertDialog.Builder(context);
+ builder.setTitle(R.string.no_flattr_token_title);
+ builder.setMessage(R.string.no_flattr_token_msg);
+ builder.setPositiveButton(R.string.authenticate_now_label,
+ new OnClickListener() {
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ context.startActivity(new Intent(context,
+ FlattrAuthActivity.class));
+ }
+
+ });
+ builder.setNegativeButton(R.string.visit_website_label,
+ new OnClickListener() {
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ Uri uri = Uri.parse(url);
+ context.startActivity(new Intent(Intent.ACTION_VIEW,
+ uri));
+ }
+
+ });
+ builder.create().show();
+ }
+
+ private static void showForbiddenDialog(final Context context,
+ final String url) {
+ AlertDialog.Builder builder = new AlertDialog.Builder(context);
+ builder.setTitle(R.string.action_forbidden_title);
+ builder.setMessage(R.string.action_forbidden_msg);
+ builder.setPositiveButton(R.string.authenticate_now_label,
+ new OnClickListener() {
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ context.startActivity(new Intent(context,
+ FlattrAuthActivity.class));
+ }
+
+ });
+ builder.setNegativeButton(R.string.visit_website_label,
+ new OnClickListener() {
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ Uri uri = Uri.parse(url);
+ context.startActivity(new Intent(Intent.ACTION_VIEW,
+ uri));
+ }
+
+ });
+ builder.create().show();
+ }
+
+ private static void showErrorDialog(final Context context, final String msg) {
+ AlertDialog.Builder builder = new AlertDialog.Builder(context);
+ builder.setTitle(R.string.error_label);
+ builder.setMessage(msg);
+ builder.setNeutralButton(android.R.string.ok, new OnClickListener() {
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ dialog.cancel();
+ }
+ });
+ builder.create().show();
+ }
+}
diff --git a/src/de/danoeh/antennapod/util/MediaPlayerError.java b/src/de/danoeh/antennapod/util/MediaPlayerError.java
new file mode 100644
index 000000000..0ce95fe65
--- /dev/null
+++ b/src/de/danoeh/antennapod/util/MediaPlayerError.java
@@ -0,0 +1,23 @@
+package de.danoeh.antennapod.util;
+
+import de.danoeh.antennapod.R;
+import android.content.Context;
+import android.media.MediaPlayer;
+
+/** Utility class for MediaPlayer errors. */
+public class MediaPlayerError {
+
+ /** Get a human-readable string for a specific error code. */
+ public static String getErrorString(Context context, int code) {
+ int resId;
+ switch(code) {
+ case MediaPlayer.MEDIA_ERROR_SERVER_DIED:
+ resId = R.string.playback_error_server_died;
+ break;
+ default:
+ resId = R.string.playback_error_unknown;
+ break;
+ }
+ return context.getString(resId);
+ }
+}
diff --git a/src/de/danoeh/antennapod/util/NumberGenerator.java b/src/de/danoeh/antennapod/util/NumberGenerator.java
new file mode 100644
index 000000000..6f9ac2e78
--- /dev/null
+++ b/src/de/danoeh/antennapod/util/NumberGenerator.java
@@ -0,0 +1,25 @@
+package de.danoeh.antennapod.util;
+
+import java.util.Random;
+import android.util.Log;
+
+/**Utility class for creating large random numbers.*/
+public final class NumberGenerator {
+ /** Class shall not be instantiated.*/
+ private NumberGenerator() {
+ }
+
+ /**Logging tag.*/
+ private static final String TAG = "NumberGenerator";
+
+ /** Takes a string and generates a random value out of
+ * the hash-value of that string.
+ * @param strSeed The string to take for the return value
+ * @return The generated random value
+ * */
+ public static long generateLong(final String strSeed) {
+ long seed = (long) strSeed.hashCode();
+ Log.d(TAG, "Taking " + seed + " as seed.");
+ return new Random(seed).nextLong();
+ }
+}
diff --git a/src/de/danoeh/antennapod/util/ShareUtils.java b/src/de/danoeh/antennapod/util/ShareUtils.java
new file mode 100644
index 000000000..2d6dee138
--- /dev/null
+++ b/src/de/danoeh/antennapod/util/ShareUtils.java
@@ -0,0 +1,34 @@
+package de.danoeh.antennapod.util;
+
+import de.danoeh.antennapod.feed.Feed;
+import de.danoeh.antennapod.feed.FeedItem;
+import android.content.Context;
+import android.content.Intent;
+
+/** Utility methods for sharing data */
+public class ShareUtils {
+ private static final String TAG = "ShareUtils";
+
+ private ShareUtils() {}
+
+ private static void shareLink(Context context, String link) {
+ Intent i = new Intent(Intent.ACTION_SEND);
+ i.setType("text/plain");
+ i.putExtra(Intent.EXTRA_SUBJECT, "Sharing URL");
+ i.putExtra(Intent.EXTRA_TEXT, link);
+ context.startActivity(Intent.createChooser(i, "Share URL"));
+ }
+
+ public static void shareFeedItemLink(Context context, FeedItem item) {
+ shareLink(context, item.getLink());
+ }
+
+ public static void shareFeedDownloadLink(Context context, Feed feed) {
+ shareLink(context, feed.getDownload_url());
+ }
+
+ public static void shareFeedlink(Context context, Feed feed) {
+ shareLink(context, feed.getLink());
+ }
+
+}
diff --git a/src/de/danoeh/antennapod/util/StorageUtils.java b/src/de/danoeh/antennapod/util/StorageUtils.java
new file mode 100644
index 000000000..942c333fb
--- /dev/null
+++ b/src/de/danoeh/antennapod/util/StorageUtils.java
@@ -0,0 +1,28 @@
+package de.danoeh.antennapod.util;
+
+import de.danoeh.antennapod.activity.StorageErrorActivity;
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Environment;
+
+/** Utility functions for handling storage errors */
+public class StorageUtils {
+ public static boolean storageAvailable() {
+ String state = Environment.getExternalStorageState();
+ return state.equals(Environment.MEDIA_MOUNTED);
+ }
+
+ /**Checks if external storage is available. If external storage isn't
+ * available, the current activity is finsished an an error activity is launched.
+ * @param activity the activity which would be finished if no storage is available
+ * @return true if external storage is available
+ */
+ public static boolean checkStorageAvailability(Activity activity) {
+ boolean storageAvailable = storageAvailable();
+ if (!storageAvailable) {
+ activity.finish();
+ activity.startActivity(new Intent(activity, StorageErrorActivity.class));
+ }
+ return storageAvailable;
+ }
+}
diff --git a/src/de/danoeh/antennapod/util/URLChecker.java b/src/de/danoeh/antennapod/util/URLChecker.java
new file mode 100644
index 000000000..f5e202946
--- /dev/null
+++ b/src/de/danoeh/antennapod/util/URLChecker.java
@@ -0,0 +1,39 @@
+package de.danoeh.antennapod.util;
+
+import android.util.Log;
+
+/** Provides methods for checking and editing a URL.*/
+public final class URLChecker {
+
+ /**Class shall not be instantiated.*/
+ private URLChecker() {
+ }
+
+ /**Logging tag.*/
+ private static final String TAG = "URLChecker";
+ /**Indicator for URLs made by Feedburner.*/
+ private static final String FEEDBURNER_URL = "feeds.feedburner.com";
+ /**Prefix that is appended to URLs by Feedburner.*/
+ private static final String FEEDBURNER_PREFIX = "?format=xml";
+
+ /** Checks if URL is valid and modifies it if necessary.
+ * @param url The url which is going to be prepared
+ * @return The prepared url
+ * */
+ public static String prepareURL(final String url) {
+ StringBuilder builder = new StringBuilder();
+
+ if (!url.startsWith("http")) {
+ builder.append("http://");
+ Log.d(TAG, "Missing http; appending");
+ }
+ builder.append(url);
+
+ if (url.contains(FEEDBURNER_URL)) {
+ Log.d(TAG,
+ "URL seems to be Feedburner URL; appending prefix");
+ builder.append(FEEDBURNER_PREFIX);
+ }
+ return builder.toString();
+ }
+}