diff --git a/src/de/danoeh/antennapod/activity/AddFeedActivity.java b/src/de/danoeh/antennapod/activity/AddFeedActivity.java index 305e1556b..a5185bf9b 100644 --- a/src/de/danoeh/antennapod/activity/AddFeedActivity.java +++ b/src/de/danoeh/antennapod/activity/AddFeedActivity.java @@ -35,17 +35,11 @@ public class AddFeedActivity extends SherlockActivity { private static final String TAG = "AddFeedActivity"; private DownloadRequester requester; - private FeedManager manager; private EditText etxtFeedurl; private Button butBrowseMiroGuide; private Button butConfirm; private Button butCancel; - private long downloadId; - - private boolean hasImage; - private boolean isWaitingForImage = false; - private long imageDownloadId; private ProgressDialog progDialog; @@ -56,26 +50,7 @@ public class AddFeedActivity extends SherlockActivity { setContentView(R.layout.addfeed); requester = DownloadRequester.getInstance(); - manager = FeedManager.getInstance(); - - progDialog = new ProgressDialog(this) { - @Override - public void onBackPressed() { - if (isWaitingForImage) { - requester.cancelDownload(getContext(), imageDownloadId); - } else { - requester.cancelDownload(getContext(), downloadId); - } - - try { - unregisterReceiver(downloadCompleted); - } catch (IllegalArgumentException e) { - // ignore - } - dismiss(); - } - - }; + progDialog = new ProgressDialog(this); etxtFeedurl = (EditText) findViewById(R.id.etxtFeedurl); butBrowseMiroGuide = (Button) findViewById(R.id.butBrowseMiroguide); @@ -137,12 +112,6 @@ public class AddFeedActivity extends SherlockActivity { @Override protected void onPause() { super.onPause(); - try { - unregisterReceiver(downloadCompleted); - } catch (IllegalArgumentException e) { - // ignore - } - } /** Read the url text field and start downloading a new feed. */ @@ -152,29 +121,21 @@ public class AddFeedActivity extends SherlockActivity { if (url != null) { final Feed feed = new Feed(url, new Date()); - final ConnectionTester conTester = new ConnectionTester(url, this, + final ConnectionTester conTester = new ConnectionTester(url, new ConnectionTester.Callback() { @Override public void onConnectionSuccessful() { - downloadId = requester.downloadFeed( - AddFeedActivity.this, feed); - + requester.downloadFeed(AddFeedActivity.this, feed); + if (progDialog.isShowing()) { + progDialog.dismiss(); + finish(); + } } @Override - public void onConnectionFailure() { - int reason = DownloadError.ERROR_CONNECTION_ERROR; - long statusId = manager.addDownloadStatus( - AddFeedActivity.this, new DownloadStatus( - feed, reason, false)); - Intent intent = new Intent( - DownloadService.ACTION_DOWNLOAD_HANDLED); - intent.putExtra(DownloadService.EXTRA_DOWNLOAD_ID, - downloadId); - intent.putExtra(DownloadService.EXTRA_STATUS_ID, - statusId); - AddFeedActivity.this.sendBroadcast(intent); + public void onConnectionFailure(int reason) { + handleDownloadError(reason); } }); observeDownload(feed); @@ -187,33 +148,13 @@ public class AddFeedActivity extends SherlockActivity { private void observeDownload(Feed feed) { progDialog.show(); progDialog.setMessage("Downloading Feed"); - registerReceiver(downloadCompleted, new IntentFilter( - DownloadService.ACTION_DOWNLOAD_HANDLED)); } - /** - * Set the message text of the progress dialog to the current status of the - * download. - */ - private void updateProgDialog(final String msg) { - if (progDialog.isShowing()) { - runOnUiThread(new Runnable() { - - @Override - public void run() { - progDialog.setMessage(msg); - - } - - }); - } - } - - private void handleDownloadError(DownloadStatus status) { + private void handleDownloadError(int reason) { final AlertDialog errorDialog = new AlertDialog.Builder(this).create(); errorDialog.setTitle(R.string.error_label); errorDialog.setMessage(getString(R.string.error_msg_prefix) + " " - + DownloadError.getErrorString(this, status.getReason())); + + DownloadError.getErrorString(this, reason)); errorDialog.setButton("OK", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { @@ -225,44 +166,4 @@ public class AddFeedActivity extends SherlockActivity { } errorDialog.show(); } - - private BroadcastReceiver downloadCompleted = new BroadcastReceiver() { - - @Override - public void onReceive(Context context, Intent intent) { - long receivedDownloadId = intent.getLongExtra( - DownloadService.EXTRA_DOWNLOAD_ID, -1); - if (receivedDownloadId == downloadId - || (isWaitingForImage && receivedDownloadId == imageDownloadId)) { - long statusId = intent.getLongExtra( - DownloadService.EXTRA_STATUS_ID, 0); - DownloadStatus status = manager.getDownloadStatus(statusId); - if (status.isSuccessful()) { - if (!isWaitingForImage) { - hasImage = intent.getBooleanExtra( - DownloadService.EXTRA_FEED_HAS_IMAGE, false); - if (!hasImage) { - progDialog.dismiss(); - finish(); - } else { - imageDownloadId = intent - .getLongExtra( - DownloadService.EXTRA_IMAGE_DOWNLOAD_ID, - -1); - isWaitingForImage = true; - updateProgDialog("Downloading Image"); - } - } else { - progDialog.dismiss(); - finish(); - } - } else { - handleDownloadError(status); - } - } - - } - - }; - } diff --git a/src/de/danoeh/antennapod/feed/FeedManager.java b/src/de/danoeh/antennapod/feed/FeedManager.java index 981247792..6644d1878 100644 --- a/src/de/danoeh/antennapod/feed/FeedManager.java +++ b/src/de/danoeh/antennapod/feed/FeedManager.java @@ -5,6 +5,9 @@ import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.List; +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; +import java.util.concurrent.ThreadFactory; import de.danoeh.antennapod.AppConfig; import de.danoeh.antennapod.activity.AudioplayerActivity; @@ -58,6 +61,8 @@ public class FeedManager { /** Should be used to change the content of the arrays from another thread. */ private Handler contentChanger; + /** Ensures that there are no parallel db operations. */ + private Executor dbExec; /** Prevents user from starting several feed updates at the same time. */ private static boolean isStartingFeedRefresh = false; @@ -70,6 +75,14 @@ public class FeedManager { downloadLog = new ArrayList(); queue = Collections.synchronizedList(new ArrayList()); contentChanger = new Handler(); + dbExec = Executors.newSingleThreadExecutor(new ThreadFactory() { + + @Override + public Thread newThread(Runnable r) { + Thread t = new Thread(r); + t.setPriority(Thread.MIN_PRIORITY); + return t; + }}); } public static FeedManager getInstance() { @@ -301,16 +314,15 @@ public class FeedManager { new Date())); } - public long addDownloadStatus(Context context, DownloadStatus status) { + public void addDownloadStatus(Context context, DownloadStatus status) { PodDBAdapter adapter = new PodDBAdapter(context); downloadLog.add(status); adapter.open(); if (downloadLog.size() > DOWNLOAD_LOG_SIZE) { adapter.removeDownloadStatus(downloadLog.remove(0)); } - long result = adapter.setDownloadStatus(status); + adapter.setDownloadStatus(status); adapter.close(); - return result; } public void addQueueItem(final Context context, final FeedItem item) { @@ -490,32 +502,29 @@ public class FeedManager { } /** Updates Information of an existing Feed. Uses external adapter. */ - public long setFeed(Feed feed, PodDBAdapter adapter) { + public void setFeed(Feed feed, PodDBAdapter adapter) { if (adapter != null) { - return adapter.setFeed(feed); + adapter.setFeed(feed); } else { Log.w(TAG, "Adapter in setFeed was null"); - return 0; } } /** Updates Information of an existing Feeditem. Uses external adapter. */ - public long setFeedItem(FeedItem item, PodDBAdapter adapter) { + public void setFeedItem(FeedItem item, PodDBAdapter adapter) { if (adapter != null) { - return adapter.setSingleFeedItem(item); + adapter.setSingleFeedItem(item); } else { Log.w(TAG, "Adapter in setFeedItem was null"); - return 0; } } /** Updates Information of an existing Feedimage. Uses external adapter. */ - public long setFeedImage(FeedImage image, PodDBAdapter adapter) { + public void setFeedImage(FeedImage image, PodDBAdapter adapter) { if (adapter != null) { - return adapter.setImage(image); + adapter.setImage(image); } else { Log.w(TAG, "Adapter in setFeedImage was null"); - return 0; } } @@ -523,12 +532,11 @@ public class FeedManager { * Updates Information of an existing Feedmedia object. Uses external * adapter. */ - public long setFeedImage(FeedMedia media, PodDBAdapter adapter) { + public void setFeedImage(FeedMedia media, PodDBAdapter adapter) { if (adapter != null) { - return adapter.setMedia(media); + adapter.setMedia(media); } else { Log.w(TAG, "Adapter in setFeedMedia was null"); - return 0; } } @@ -536,48 +544,44 @@ public class FeedManager { * Updates Information of an existing Feed. Creates and opens its own * adapter. */ - public long setFeed(Context context, Feed feed) { + public void setFeed(Context context, Feed feed) { PodDBAdapter adapter = new PodDBAdapter(context); adapter.open(); - long result = adapter.setFeed(feed); + adapter.setFeed(feed); adapter.close(); - return result; } /** * Updates information of an existing FeedItem. Creates and opens its own * adapter. */ - public long setFeedItem(Context context, FeedItem item) { + public void setFeedItem(Context context, FeedItem item) { PodDBAdapter adapter = new PodDBAdapter(context); adapter.open(); - long result = adapter.setSingleFeedItem(item); + adapter.setSingleFeedItem(item); adapter.close(); - return result; } /** * Updates information of an existing FeedImage. Creates and opens its own * adapter. */ - public long setFeedImage(Context context, FeedImage image) { + public void setFeedImage(Context context, FeedImage image) { PodDBAdapter adapter = new PodDBAdapter(context); adapter.open(); - long result = adapter.setImage(image); + adapter.setImage(image); adapter.close(); - return result; } /** * Updates information of an existing FeedMedia object. Creates and opens * its own adapter. */ - public long setFeedMedia(Context context, FeedMedia media) { + public void setFeedMedia(Context context, FeedMedia media) { PodDBAdapter adapter = new PodDBAdapter(context); adapter.open(); - long result = adapter.setMedia(media); + adapter.setMedia(media); adapter.close(); - return result; } /** Get a Feed by its id */ @@ -643,9 +647,9 @@ public class FeedManager { return null; } - public DownloadStatus getDownloadStatus(long statusId) { + public DownloadStatus getDownloadStatus(FeedFile feedFile) { for (DownloadStatus status : downloadLog) { - if (status.getId() == statusId) { + if (status.getFeedFile() == feedFile) { return status; } } diff --git a/src/de/danoeh/antennapod/service/DownloadService.java b/src/de/danoeh/antennapod/service/DownloadService.java index 30288efc0..d8b93ac77 100644 --- a/src/de/danoeh/antennapod/service/DownloadService.java +++ b/src/de/danoeh/antennapod/service/DownloadService.java @@ -65,8 +65,6 @@ public class DownloadService extends Service { public static final String ACTION_DOWNLOAD_HANDLED = "action.de.danoeh.antennapod.service.download_handled"; /** True if handled feed has an image. */ public static final String EXTRA_FEED_HAS_IMAGE = "extra.de.danoeh.antennapod.service.feed_has_image"; - /** ID of DownloadStatus. */ - public static final String EXTRA_STATUS_ID = "extra.de.danoeh.antennapod.service.feedfile_id"; public static final String EXTRA_DOWNLOAD_ID = "extra.de.danoeh.antennapod.service.download_id"; public static final String EXTRA_IMAGE_DOWNLOAD_ID = "extra.de.danoeh.antennapod.service.image_download_id"; @@ -123,7 +121,8 @@ public class DownloadService extends Service { Log.e(TAG, "Thread exited with uncaught exception"); ex.printStackTrace(); queryDownloads(); - }}); + } + }); return t; } }); @@ -258,11 +257,11 @@ public class DownloadService extends Service { Log.e(TAG, "Download failed"); Log.e(TAG, "reason code is " + reason); successful = false; - long statusId = saveDownloadStatus(new DownloadStatus( - download, reason, successful)); + saveDownloadStatus(new DownloadStatus(download, + reason, successful)); requester.removeDownload(download); sendDownloadHandledIntent(download.getDownloadId(), - statusId, false, 0); + false, 0); download.setDownloadId(0); } @@ -288,16 +287,15 @@ public class DownloadService extends Service { * @param status * the download that is going to be saved */ - private long saveDownloadStatus(DownloadStatus status) { + private void saveDownloadStatus(DownloadStatus status) { completedDownloads.add(status); - return manager.addDownloadStatus(this, status); + manager.addDownloadStatus(this, status); } - private void sendDownloadHandledIntent(long downloadId, long statusId, + private void sendDownloadHandledIntent(long downloadId, boolean feedHasImage, long imageDownloadId) { Intent intent = new Intent(ACTION_DOWNLOAD_HANDLED); intent.putExtra(EXTRA_DOWNLOAD_ID, downloadId); - intent.putExtra(EXTRA_STATUS_ID, statusId); intent.putExtra(EXTRA_FEED_HAS_IMAGE, feedHasImage); if (feedHasImage) { intent.putExtra(EXTRA_IMAGE_DOWNLOAD_ID, imageDownloadId); @@ -448,7 +446,8 @@ public class DownloadService extends Service { if (AppConfig.DEBUG) Log.d(TAG, "Feed has image; Downloading...."); savedFeed.getImage().setFeed(savedFeed); - imageId = requester.downloadImage(service, savedFeed.getImage()); + imageId = requester.downloadImage(service, + savedFeed.getImage()); hasImage = true; } @@ -475,13 +474,12 @@ public class DownloadService extends Service { } requester.removeDownload(feed); - //cleanup(); + // cleanup(); if (savedFeed == null) { savedFeed = feed; } - long statusId = saveDownloadStatus(new DownloadStatus(savedFeed, - reason, successful)); - sendDownloadHandledIntent(downloadId, statusId, hasImage, imageId); + saveDownloadStatus(new DownloadStatus(savedFeed, reason, successful)); + sendDownloadHandledIntent(downloadId, hasImage, imageId); queryDownloads(); } @@ -528,15 +526,15 @@ public class DownloadService extends Service { image.setDownloaded(true); requester.removeDownload(image); - long statusId = saveDownloadStatus(new DownloadStatus(image, 0, - true)); - sendDownloadHandledIntent(image.getDownloadId(), statusId, false, 0); + saveDownloadStatus(new DownloadStatus(image, 0, true)); + sendDownloadHandledIntent(image.getDownloadId(), false, 0); image.setDownloadId(0); manager.setFeedImage(service, image); if (image.getFeed() != null) { manager.setFeed(service, image.getFeed()); } else { - Log.e(TAG, "Image has no feed, image might not be saved correctly!"); + Log.e(TAG, + "Image has no feed, image might not be saved correctly!"); } queryDownloads(); } @@ -568,15 +566,14 @@ public class DownloadService extends Service { if (AppConfig.DEBUG) Log.d(TAG, "Duration of file is " + media.getDuration()); mediaplayer.reset(); - long statusId = saveDownloadStatus(new DownloadStatus(media, 0, - true)); - sendDownloadHandledIntent(media.getDownloadId(), statusId, false, 0); + saveDownloadStatus(new DownloadStatus(media, 0, true)); + sendDownloadHandledIntent(media.getDownloadId(), false, 0); media.setDownloadId(0); manager.setFeedMedia(service, media); boolean autoQueue = PreferenceManager.getDefaultSharedPreferences( getApplicationContext()).getBoolean( PodcastApp.PREF_AUTO_QUEUE, true); - + if (!manager.isInQueue(media.getItem())) { // Auto-queue if (autoQueue) { @@ -588,9 +585,10 @@ public class DownloadService extends Service { Log.d(TAG, "Autoqueue is disabled"); } } else { - if (AppConfig.DEBUG) Log.d(TAG, "Item is already in queue"); + if (AppConfig.DEBUG) + Log.d(TAG, "Item is already in queue"); } - + queryDownloads(); } } diff --git a/src/de/danoeh/antennapod/util/ConnectionTester.java b/src/de/danoeh/antennapod/util/ConnectionTester.java index 2318c0c59..2ca9b3218 100644 --- a/src/de/danoeh/antennapod/util/ConnectionTester.java +++ b/src/de/danoeh/antennapod/util/ConnectionTester.java @@ -9,60 +9,73 @@ import java.net.URLConnection; import de.danoeh.antennapod.AppConfig; import android.content.Context; +import android.os.Handler; 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) { + + private Handler handler; + + public ConnectionTester(String url, Callback callback) { super(); this.strUrl = url; - this.context = context; this.callback = callback; - connectTimeout = 500; - readTimeout = connectTimeout; + this.handler = new Handler(); } - - @Override public void run() { - if (AppConfig.DEBUG) Log.d(TAG, "Testing connection"); - try { + if (AppConfig.DEBUG) + Log.d(TAG, "Testing connection"); + try { URL url = new URL(strUrl); - HttpURLConnection con = (HttpURLConnection) url.openConnection(); - con.connect(); - callback.onConnectionSuccessful(); - if (AppConfig.DEBUG) Log.d(TAG, "Connection seems to work"); + HttpURLConnection con = (HttpURLConnection) url.openConnection(); + con.connect(); + handler.post(new Runnable() { + @Override + public void run() { + callback.onConnectionSuccessful(); + } + }); if (AppConfig.DEBUG) + Log.d(TAG, "Connection seems to work"); } catch (MalformedURLException e) { e.printStackTrace(); reason = DownloadError.ERROR_CONNECTION_ERROR; - if (AppConfig.DEBUG) Log.d(TAG, "Connection failed"); - callback.onConnectionFailure(); + if (AppConfig.DEBUG) + Log.d(TAG, "Connection failed"); + handler.post(new Runnable() { + @Override + public void run() { + callback.onConnectionFailure(reason); + } + }); } catch (IOException e) { e.printStackTrace(); reason = DownloadError.ERROR_CONNECTION_ERROR; - if (AppConfig.DEBUG) Log.d(TAG, "Connection failed"); - callback.onConnectionFailure(); + if (AppConfig.DEBUG) + Log.d(TAG, "Connection failed"); + handler.post(new Runnable() { + @Override + public void run() { + callback.onConnectionFailure(reason); + } + }); } } - - + public static abstract class Callback { public abstract void onConnectionSuccessful(); - public abstract void onConnectionFailure(); + + public abstract void onConnectionFailure(int reason); } - + public int getReason() { return reason; } - }