Simplified AddFeedActivity

This commit is contained in:
daniel oeh 2012-08-11 21:37:28 +02:00
parent 8a52f216ea
commit e4cbebde10
4 changed files with 105 additions and 189 deletions

View File

@ -35,17 +35,11 @@ public class AddFeedActivity extends SherlockActivity {
private static final String TAG = "AddFeedActivity"; private static final String TAG = "AddFeedActivity";
private DownloadRequester requester; private DownloadRequester requester;
private FeedManager manager;
private EditText etxtFeedurl; private EditText etxtFeedurl;
private Button butBrowseMiroGuide; private Button butBrowseMiroGuide;
private Button butConfirm; private Button butConfirm;
private Button butCancel; private Button butCancel;
private long downloadId;
private boolean hasImage;
private boolean isWaitingForImage = false;
private long imageDownloadId;
private ProgressDialog progDialog; private ProgressDialog progDialog;
@ -56,26 +50,7 @@ public class AddFeedActivity extends SherlockActivity {
setContentView(R.layout.addfeed); setContentView(R.layout.addfeed);
requester = DownloadRequester.getInstance(); requester = DownloadRequester.getInstance();
manager = FeedManager.getInstance(); progDialog = new ProgressDialog(this);
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();
}
};
etxtFeedurl = (EditText) findViewById(R.id.etxtFeedurl); etxtFeedurl = (EditText) findViewById(R.id.etxtFeedurl);
butBrowseMiroGuide = (Button) findViewById(R.id.butBrowseMiroguide); butBrowseMiroGuide = (Button) findViewById(R.id.butBrowseMiroguide);
@ -137,12 +112,6 @@ public class AddFeedActivity extends SherlockActivity {
@Override @Override
protected void onPause() { protected void onPause() {
super.onPause(); super.onPause();
try {
unregisterReceiver(downloadCompleted);
} catch (IllegalArgumentException e) {
// ignore
}
} }
/** Read the url text field and start downloading a new feed. */ /** Read the url text field and start downloading a new feed. */
@ -152,29 +121,21 @@ public class AddFeedActivity extends SherlockActivity {
if (url != null) { if (url != null) {
final Feed feed = new Feed(url, new Date()); final Feed feed = new Feed(url, new Date());
final ConnectionTester conTester = new ConnectionTester(url, this, final ConnectionTester conTester = new ConnectionTester(url,
new ConnectionTester.Callback() { new ConnectionTester.Callback() {
@Override @Override
public void onConnectionSuccessful() { public void onConnectionSuccessful() {
downloadId = requester.downloadFeed( requester.downloadFeed(AddFeedActivity.this, feed);
AddFeedActivity.this, feed); if (progDialog.isShowing()) {
progDialog.dismiss();
finish();
}
} }
@Override @Override
public void onConnectionFailure() { public void onConnectionFailure(int reason) {
int reason = DownloadError.ERROR_CONNECTION_ERROR; handleDownloadError(reason);
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);
} }
}); });
observeDownload(feed); observeDownload(feed);
@ -187,33 +148,13 @@ public class AddFeedActivity extends SherlockActivity {
private void observeDownload(Feed feed) { private void observeDownload(Feed feed) {
progDialog.show(); progDialog.show();
progDialog.setMessage("Downloading Feed"); progDialog.setMessage("Downloading Feed");
registerReceiver(downloadCompleted, new IntentFilter(
DownloadService.ACTION_DOWNLOAD_HANDLED));
} }
/** private void handleDownloadError(int reason) {
* 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) {
final AlertDialog errorDialog = new AlertDialog.Builder(this).create(); final AlertDialog errorDialog = new AlertDialog.Builder(this).create();
errorDialog.setTitle(R.string.error_label); errorDialog.setTitle(R.string.error_label);
errorDialog.setMessage(getString(R.string.error_msg_prefix) + " " errorDialog.setMessage(getString(R.string.error_msg_prefix) + " "
+ DownloadError.getErrorString(this, status.getReason())); + DownloadError.getErrorString(this, reason));
errorDialog.setButton("OK", new DialogInterface.OnClickListener() { errorDialog.setButton("OK", new DialogInterface.OnClickListener() {
@Override @Override
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
@ -225,44 +166,4 @@ public class AddFeedActivity extends SherlockActivity {
} }
errorDialog.show(); 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);
}
}
}
};
} }

View File

@ -5,6 +5,9 @@ import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.List; 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.AppConfig;
import de.danoeh.antennapod.activity.AudioplayerActivity; 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. */ /** Should be used to change the content of the arrays from another thread. */
private Handler contentChanger; 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. */ /** Prevents user from starting several feed updates at the same time. */
private static boolean isStartingFeedRefresh = false; private static boolean isStartingFeedRefresh = false;
@ -70,6 +75,14 @@ public class FeedManager {
downloadLog = new ArrayList<DownloadStatus>(); downloadLog = new ArrayList<DownloadStatus>();
queue = Collections.synchronizedList(new ArrayList<FeedItem>()); queue = Collections.synchronizedList(new ArrayList<FeedItem>());
contentChanger = new Handler(); 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() { public static FeedManager getInstance() {
@ -301,16 +314,15 @@ public class FeedManager {
new Date())); new Date()));
} }
public long addDownloadStatus(Context context, DownloadStatus status) { public void addDownloadStatus(Context context, DownloadStatus status) {
PodDBAdapter adapter = new PodDBAdapter(context); PodDBAdapter adapter = new PodDBAdapter(context);
downloadLog.add(status); downloadLog.add(status);
adapter.open(); adapter.open();
if (downloadLog.size() > DOWNLOAD_LOG_SIZE) { if (downloadLog.size() > DOWNLOAD_LOG_SIZE) {
adapter.removeDownloadStatus(downloadLog.remove(0)); adapter.removeDownloadStatus(downloadLog.remove(0));
} }
long result = adapter.setDownloadStatus(status); adapter.setDownloadStatus(status);
adapter.close(); adapter.close();
return result;
} }
public void addQueueItem(final Context context, final FeedItem item) { 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. */ /** 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) { if (adapter != null) {
return adapter.setFeed(feed); adapter.setFeed(feed);
} else { } else {
Log.w(TAG, "Adapter in setFeed was null"); Log.w(TAG, "Adapter in setFeed was null");
return 0;
} }
} }
/** Updates Information of an existing Feeditem. Uses external adapter. */ /** 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) { if (adapter != null) {
return adapter.setSingleFeedItem(item); adapter.setSingleFeedItem(item);
} else { } else {
Log.w(TAG, "Adapter in setFeedItem was null"); Log.w(TAG, "Adapter in setFeedItem was null");
return 0;
} }
} }
/** Updates Information of an existing Feedimage. Uses external adapter. */ /** 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) { if (adapter != null) {
return adapter.setImage(image); adapter.setImage(image);
} else { } else {
Log.w(TAG, "Adapter in setFeedImage was null"); 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 * Updates Information of an existing Feedmedia object. Uses external
* adapter. * adapter.
*/ */
public long setFeedImage(FeedMedia media, PodDBAdapter adapter) { public void setFeedImage(FeedMedia media, PodDBAdapter adapter) {
if (adapter != null) { if (adapter != null) {
return adapter.setMedia(media); adapter.setMedia(media);
} else { } else {
Log.w(TAG, "Adapter in setFeedMedia was null"); 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 * Updates Information of an existing Feed. Creates and opens its own
* adapter. * adapter.
*/ */
public long setFeed(Context context, Feed feed) { public void setFeed(Context context, Feed feed) {
PodDBAdapter adapter = new PodDBAdapter(context); PodDBAdapter adapter = new PodDBAdapter(context);
adapter.open(); adapter.open();
long result = adapter.setFeed(feed); adapter.setFeed(feed);
adapter.close(); adapter.close();
return result;
} }
/** /**
* Updates information of an existing FeedItem. Creates and opens its own * Updates information of an existing FeedItem. Creates and opens its own
* adapter. * adapter.
*/ */
public long setFeedItem(Context context, FeedItem item) { public void setFeedItem(Context context, FeedItem item) {
PodDBAdapter adapter = new PodDBAdapter(context); PodDBAdapter adapter = new PodDBAdapter(context);
adapter.open(); adapter.open();
long result = adapter.setSingleFeedItem(item); adapter.setSingleFeedItem(item);
adapter.close(); adapter.close();
return result;
} }
/** /**
* Updates information of an existing FeedImage. Creates and opens its own * Updates information of an existing FeedImage. Creates and opens its own
* adapter. * adapter.
*/ */
public long setFeedImage(Context context, FeedImage image) { public void setFeedImage(Context context, FeedImage image) {
PodDBAdapter adapter = new PodDBAdapter(context); PodDBAdapter adapter = new PodDBAdapter(context);
adapter.open(); adapter.open();
long result = adapter.setImage(image); adapter.setImage(image);
adapter.close(); adapter.close();
return result;
} }
/** /**
* Updates information of an existing FeedMedia object. Creates and opens * Updates information of an existing FeedMedia object. Creates and opens
* its own adapter. * its own adapter.
*/ */
public long setFeedMedia(Context context, FeedMedia media) { public void setFeedMedia(Context context, FeedMedia media) {
PodDBAdapter adapter = new PodDBAdapter(context); PodDBAdapter adapter = new PodDBAdapter(context);
adapter.open(); adapter.open();
long result = adapter.setMedia(media); adapter.setMedia(media);
adapter.close(); adapter.close();
return result;
} }
/** Get a Feed by its id */ /** Get a Feed by its id */
@ -643,9 +647,9 @@ public class FeedManager {
return null; return null;
} }
public DownloadStatus getDownloadStatus(long statusId) { public DownloadStatus getDownloadStatus(FeedFile feedFile) {
for (DownloadStatus status : downloadLog) { for (DownloadStatus status : downloadLog) {
if (status.getId() == statusId) { if (status.getFeedFile() == feedFile) {
return status; return status;
} }
} }

View File

@ -65,8 +65,6 @@ public class DownloadService extends Service {
public static final String ACTION_DOWNLOAD_HANDLED = "action.de.danoeh.antennapod.service.download_handled"; public static final String ACTION_DOWNLOAD_HANDLED = "action.de.danoeh.antennapod.service.download_handled";
/** True if handled feed has an image. */ /** True if handled feed has an image. */
public static final String EXTRA_FEED_HAS_IMAGE = "extra.de.danoeh.antennapod.service.feed_has_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_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"; 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"); Log.e(TAG, "Thread exited with uncaught exception");
ex.printStackTrace(); ex.printStackTrace();
queryDownloads(); queryDownloads();
}}); }
});
return t; return t;
} }
}); });
@ -258,11 +257,11 @@ public class DownloadService extends Service {
Log.e(TAG, "Download failed"); Log.e(TAG, "Download failed");
Log.e(TAG, "reason code is " + reason); Log.e(TAG, "reason code is " + reason);
successful = false; successful = false;
long statusId = saveDownloadStatus(new DownloadStatus( saveDownloadStatus(new DownloadStatus(download,
download, reason, successful)); reason, successful));
requester.removeDownload(download); requester.removeDownload(download);
sendDownloadHandledIntent(download.getDownloadId(), sendDownloadHandledIntent(download.getDownloadId(),
statusId, false, 0); false, 0);
download.setDownloadId(0); download.setDownloadId(0);
} }
@ -288,16 +287,15 @@ public class DownloadService extends Service {
* @param status * @param status
* the download that is going to be saved * the download that is going to be saved
*/ */
private long saveDownloadStatus(DownloadStatus status) { private void saveDownloadStatus(DownloadStatus status) {
completedDownloads.add(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) { boolean feedHasImage, long imageDownloadId) {
Intent intent = new Intent(ACTION_DOWNLOAD_HANDLED); Intent intent = new Intent(ACTION_DOWNLOAD_HANDLED);
intent.putExtra(EXTRA_DOWNLOAD_ID, downloadId); intent.putExtra(EXTRA_DOWNLOAD_ID, downloadId);
intent.putExtra(EXTRA_STATUS_ID, statusId);
intent.putExtra(EXTRA_FEED_HAS_IMAGE, feedHasImage); intent.putExtra(EXTRA_FEED_HAS_IMAGE, feedHasImage);
if (feedHasImage) { if (feedHasImage) {
intent.putExtra(EXTRA_IMAGE_DOWNLOAD_ID, imageDownloadId); intent.putExtra(EXTRA_IMAGE_DOWNLOAD_ID, imageDownloadId);
@ -448,7 +446,8 @@ public class DownloadService extends Service {
if (AppConfig.DEBUG) if (AppConfig.DEBUG)
Log.d(TAG, "Feed has image; Downloading...."); Log.d(TAG, "Feed has image; Downloading....");
savedFeed.getImage().setFeed(savedFeed); savedFeed.getImage().setFeed(savedFeed);
imageId = requester.downloadImage(service, savedFeed.getImage()); imageId = requester.downloadImage(service,
savedFeed.getImage());
hasImage = true; hasImage = true;
} }
@ -475,13 +474,12 @@ public class DownloadService extends Service {
} }
requester.removeDownload(feed); requester.removeDownload(feed);
//cleanup(); // cleanup();
if (savedFeed == null) { if (savedFeed == null) {
savedFeed = feed; savedFeed = feed;
} }
long statusId = saveDownloadStatus(new DownloadStatus(savedFeed, saveDownloadStatus(new DownloadStatus(savedFeed, reason, successful));
reason, successful)); sendDownloadHandledIntent(downloadId, hasImage, imageId);
sendDownloadHandledIntent(downloadId, statusId, hasImage, imageId);
queryDownloads(); queryDownloads();
} }
@ -528,15 +526,15 @@ public class DownloadService extends Service {
image.setDownloaded(true); image.setDownloaded(true);
requester.removeDownload(image); requester.removeDownload(image);
long statusId = saveDownloadStatus(new DownloadStatus(image, 0, saveDownloadStatus(new DownloadStatus(image, 0, true));
true)); sendDownloadHandledIntent(image.getDownloadId(), false, 0);
sendDownloadHandledIntent(image.getDownloadId(), statusId, false, 0);
image.setDownloadId(0); image.setDownloadId(0);
manager.setFeedImage(service, image); manager.setFeedImage(service, image);
if (image.getFeed() != null) { if (image.getFeed() != null) {
manager.setFeed(service, image.getFeed()); manager.setFeed(service, image.getFeed());
} else { } 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(); queryDownloads();
} }
@ -568,15 +566,14 @@ public class DownloadService extends Service {
if (AppConfig.DEBUG) if (AppConfig.DEBUG)
Log.d(TAG, "Duration of file is " + media.getDuration()); Log.d(TAG, "Duration of file is " + media.getDuration());
mediaplayer.reset(); mediaplayer.reset();
long statusId = saveDownloadStatus(new DownloadStatus(media, 0, saveDownloadStatus(new DownloadStatus(media, 0, true));
true)); sendDownloadHandledIntent(media.getDownloadId(), false, 0);
sendDownloadHandledIntent(media.getDownloadId(), statusId, false, 0);
media.setDownloadId(0); media.setDownloadId(0);
manager.setFeedMedia(service, media); manager.setFeedMedia(service, media);
boolean autoQueue = PreferenceManager.getDefaultSharedPreferences( boolean autoQueue = PreferenceManager.getDefaultSharedPreferences(
getApplicationContext()).getBoolean( getApplicationContext()).getBoolean(
PodcastApp.PREF_AUTO_QUEUE, true); PodcastApp.PREF_AUTO_QUEUE, true);
if (!manager.isInQueue(media.getItem())) { if (!manager.isInQueue(media.getItem())) {
// Auto-queue // Auto-queue
if (autoQueue) { if (autoQueue) {
@ -588,9 +585,10 @@ public class DownloadService extends Service {
Log.d(TAG, "Autoqueue is disabled"); Log.d(TAG, "Autoqueue is disabled");
} }
} else { } else {
if (AppConfig.DEBUG) Log.d(TAG, "Item is already in queue"); if (AppConfig.DEBUG)
Log.d(TAG, "Item is already in queue");
} }
queryDownloads(); queryDownloads();
} }
} }

View File

@ -9,60 +9,73 @@ import java.net.URLConnection;
import de.danoeh.antennapod.AppConfig; import de.danoeh.antennapod.AppConfig;
import android.content.Context; import android.content.Context;
import android.os.Handler;
import android.util.Log; import android.util.Log;
/** Tests a connection before downloading something. */ /** Tests a connection before downloading something. */
public class ConnectionTester implements Runnable { public class ConnectionTester implements Runnable {
private static final String TAG = "ConnectionTester"; private static final String TAG = "ConnectionTester";
private String strUrl; private String strUrl;
private Context context;
private int connectTimeout;
private int readTimeout;
private Callback callback; private Callback callback;
private int reason; private int reason;
public ConnectionTester(String url, Context context, Callback callback) { private Handler handler;
public ConnectionTester(String url, Callback callback) {
super(); super();
this.strUrl = url; this.strUrl = url;
this.context = context;
this.callback = callback; this.callback = callback;
connectTimeout = 500; this.handler = new Handler();
readTimeout = connectTimeout;
} }
@Override @Override
public void run() { public void run() {
if (AppConfig.DEBUG) Log.d(TAG, "Testing connection"); if (AppConfig.DEBUG)
try { Log.d(TAG, "Testing connection");
try {
URL url = new URL(strUrl); URL url = new URL(strUrl);
HttpURLConnection con = (HttpURLConnection) url.openConnection(); HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.connect(); con.connect();
callback.onConnectionSuccessful(); handler.post(new Runnable() {
if (AppConfig.DEBUG) Log.d(TAG, "Connection seems to work"); @Override
public void run() {
callback.onConnectionSuccessful();
}
}); if (AppConfig.DEBUG)
Log.d(TAG, "Connection seems to work");
} catch (MalformedURLException e) { } catch (MalformedURLException e) {
e.printStackTrace(); e.printStackTrace();
reason = DownloadError.ERROR_CONNECTION_ERROR; reason = DownloadError.ERROR_CONNECTION_ERROR;
if (AppConfig.DEBUG) Log.d(TAG, "Connection failed"); if (AppConfig.DEBUG)
callback.onConnectionFailure(); Log.d(TAG, "Connection failed");
handler.post(new Runnable() {
@Override
public void run() {
callback.onConnectionFailure(reason);
}
});
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
reason = DownloadError.ERROR_CONNECTION_ERROR; reason = DownloadError.ERROR_CONNECTION_ERROR;
if (AppConfig.DEBUG) Log.d(TAG, "Connection failed"); if (AppConfig.DEBUG)
callback.onConnectionFailure(); Log.d(TAG, "Connection failed");
handler.post(new Runnable() {
@Override
public void run() {
callback.onConnectionFailure(reason);
}
});
} }
} }
public static abstract class Callback { public static abstract class Callback {
public abstract void onConnectionSuccessful(); public abstract void onConnectionSuccessful();
public abstract void onConnectionFailure();
public abstract void onConnectionFailure(int reason);
} }
public int getReason() { public int getReason() {
return reason; return reason;
} }
} }