Merge pull request #789 from mfietz/feature/confirm-download-mobile

Confirm download on mobile data connection

This seems to work well. We may want to tweak the workflow further, but we'll figure that out as we use it an in Alpha testing.
This commit is contained in:
Tom Hennen 2015-05-08 17:44:47 -04:00
commit b32fa4ec71
5 changed files with 133 additions and 39 deletions

View File

@ -10,7 +10,9 @@ import org.apache.commons.lang3.Validate;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.FeedMedia;
import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.DownloadRequester;
import de.danoeh.antennapod.core.util.LongList;
/**
* Utility methods for the action button that is displayed on the right hand side
@ -26,9 +28,21 @@ public class ActionButtonUtils {
Validate.notNull(context);
this.context = context;
drawables = context.obtainStyledAttributes(new int[]{
R.attr.av_play, R.attr.navigation_cancel, R.attr.av_download, R.attr.av_pause, R.attr.navigation_accept});
labels = new int[]{R.string.play_label, R.string.cancel_download_label, R.string.download_label, R.string.mark_read_label};
drawables = context.obtainStyledAttributes(new int[] {
R.attr.av_play,
R.attr.navigation_cancel,
R.attr.av_download,
R.attr.av_pause,
R.attr.navigation_accept,
R.attr.content_new
});
labels = new int[] {
R.string.play_label,
R.string.cancel_download_label,
R.string.download_label,
R.string.mark_read_label,
R.string.add_to_queue_label
};
}
/**
@ -50,18 +64,26 @@ public class ActionButtonUtils {
butSecondary.setContentDescription(context.getString(labels[1]));
} else {
// item is not downloaded and not being downloaded
butSecondary.setVisibility(View.VISIBLE);
butSecondary.setImageDrawable(drawables.getDrawable(2));
butSecondary.setContentDescription(context.getString(labels[2]));
LongList queueIds = DBReader.getQueueIDList(context);
if(DefaultActionButtonCallback.userAllowedMobileDownloads() ||
!DefaultActionButtonCallback.userChoseAddToQueue() || queueIds.contains(item.getId())) {
butSecondary.setVisibility(View.VISIBLE);
butSecondary.setImageDrawable(drawables.getDrawable(2));
butSecondary.setContentDescription(context.getString(labels[2]));
} else {
// mobile download not allowed yet, item is not in queue and user chose add to queue
butSecondary.setVisibility(View.VISIBLE);
butSecondary.setImageDrawable(drawables.getDrawable(5));
butSecondary.setContentDescription(context.getString(labels[4]));
}
}
} else {
// item is not being downloaded
// item is downloaded
butSecondary.setVisibility(View.VISIBLE);
if (media.isCurrentlyPlaying()) {
butSecondary.setImageDrawable(drawables.getDrawable(3));
} else {
butSecondary
.setImageDrawable(drawables.getDrawable(0));
butSecondary.setImageDrawable(drawables.getDrawable(0));
}
butSecondary.setContentDescription(context.getString(labels[0]));
}

View File

@ -1,6 +1,8 @@
package de.danoeh.antennapod.adapter;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.widget.Toast;
@ -10,41 +12,66 @@ import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.dialog.DownloadRequestErrorDialogCreator;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.FeedMedia;
import de.danoeh.antennapod.core.service.playback.PlaybackService;
import de.danoeh.antennapod.core.gpoddernet.model.GpodnetEpisodeAction;
import de.danoeh.antennapod.core.preferences.GpodnetPreferences;
import de.danoeh.antennapod.core.service.playback.PlaybackService;
import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.DBTasks;
import de.danoeh.antennapod.core.storage.DBWriter;
import de.danoeh.antennapod.core.storage.DownloadRequestException;
import de.danoeh.antennapod.core.storage.DownloadRequester;
import de.danoeh.antennapod.core.util.LongList;
import de.danoeh.antennapod.core.util.NetworkUtils;
/**
* Default implementation of an ActionButtonCallback
*/
public class DefaultActionButtonCallback implements ActionButtonCallback {
private static final String TAG = "DefaultActionButtonCallback";
private final Context context;
private static final int TEN_MINUTES_IN_MILLIS = 60 * 1000 * 10;
// remember timestamp when user allowed downloading via mobile connection
private static long allowMobileDownloadsTimestamp;
private static long onlyAddToQueueTimeStamp;
public DefaultActionButtonCallback(Context context) {
Validate.notNull(context);
this.context = context;
}
public static boolean userAllowedMobileDownloads() {
return System.currentTimeMillis() - allowMobileDownloadsTimestamp < TEN_MINUTES_IN_MILLIS;
}
public static boolean userChoseAddToQueue() {
return System.currentTimeMillis() - onlyAddToQueueTimeStamp < TEN_MINUTES_IN_MILLIS;
}
@Override
public void onActionButtonPressed(final FeedItem item) {
if (item.hasMedia()) {
final FeedMedia media = item.getMedia();
boolean isDownloading = DownloadRequester.getInstance().isDownloadingFile(media);
if (!isDownloading && !media.isDownloaded()) {
try {
DBTasks.downloadFeedItems(context, item);
Toast.makeText(context, R.string.status_downloading_label, Toast.LENGTH_SHORT).show();
} catch (DownloadRequestException e) {
e.printStackTrace();
DownloadRequestErrorDialogCreator.newRequestErrorDialog(context, e.getMessage());
LongList queueIds = DBReader.getQueueIDList(context);
if (NetworkUtils.isDownloadAllowed(context) || userAllowedMobileDownloads()) {
try {
DBTasks.downloadFeedItems(context, item);
Toast.makeText(context, R.string.status_downloading_label, Toast.LENGTH_SHORT).show();
} catch (DownloadRequestException e) {
e.printStackTrace();
DownloadRequestErrorDialogCreator.newRequestErrorDialog(context, e.getMessage());
}
} else if(userChoseAddToQueue() && !queueIds.contains(item.getId())) {
DBWriter.addQueueItem(context, item.getId());
Toast.makeText(context, R.string.added_to_queue_label, Toast.LENGTH_SHORT).show();
} else {
confirmMobileDownload(context, item);
}
} else if (isDownloading) {
DownloadRequester.getInstance().cancelDownload(context, media);
@ -79,4 +106,43 @@ public class DefaultActionButtonCallback implements ActionButtonCallback {
}
}
}
private void confirmMobileDownload(final Context context, final FeedItem item) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder
.setTitle(R.string.confirm_mobile_download_dialog_title)
.setMessage(context.getText(R.string.confirm_mobile_download_dialog_message))
.setPositiveButton(R.string.confirm_mobile_download_dialog_enable_temporarily,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
allowMobileDownloadsTimestamp = System.currentTimeMillis();
try {
DBTasks.downloadFeedItems(context, item);
Toast.makeText(context, R.string.status_downloading_label, Toast.LENGTH_SHORT).show();
} catch (DownloadRequestException e) {
e.printStackTrace();
DownloadRequestErrorDialogCreator.newRequestErrorDialog(context, e.getMessage());
}
}
});
LongList queueIds = DBReader.getQueueIDList(context);
if(!queueIds.contains(item.getId())) {
builder.setNeutralButton(R.string.confirm_mobile_download_dialog_only_add_to_queue,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
onlyAddToQueueTimeStamp = System.currentTimeMillis();
DBWriter.addQueueItem(context, item.getId());
Toast.makeText(context, R.string.added_to_queue_label, Toast.LENGTH_SHORT).show();
}
})
.setMessage(context.getText(R.string.confirm_mobile_download_dialog_message_not_in_queue));
} else {
builder.setMessage(context.getText(R.string.confirm_mobile_download_dialog_message));
}
builder.setNegativeButton(R.string.cancel_label, null)
.create()
.show();
}
}

View File

@ -3,41 +3,26 @@ package de.danoeh.antennapod.core.receiver;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.util.Log;
import de.danoeh.antennapod.core.BuildConfig;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.storage.DBTasks;
import de.danoeh.antennapod.core.util.NetworkUtils;
/**
* Refreshes all feeds when it receives an intent
*/
public class FeedUpdateReceiver extends BroadcastReceiver {
private static final String TAG = "FeedUpdateReceiver";
@Override
public void onReceive(Context context, Intent intent) {
if (BuildConfig.DEBUG)
Log.d(TAG, "Received intent");
boolean mobileUpdate = UserPreferences.isAllowMobileUpdate();
if (mobileUpdate || connectedToWifi(context)) {
Log.d(TAG, "Received intent");
if (NetworkUtils.isDownloadAllowed(context)) {
DBTasks.refreshExpiredFeeds(context);
} else {
if (BuildConfig.DEBUG)
Log.d(TAG,
"Blocking automatic update: no wifi available / no mobile updates allowed");
Log.d(TAG, "Blocking automatic update: no wifi available / no mobile updates allowed");
}
}
private boolean connectedToWifi(Context context) {
ConnectivityManager connManager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo mWifi = connManager
.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
return mWifi.isConnected();
}
}

View File

@ -6,12 +6,13 @@ import android.net.NetworkInfo;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.util.Log;
import de.danoeh.antennapod.core.BuildConfig;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import java.util.Arrays;
import java.util.List;
import de.danoeh.antennapod.core.BuildConfig;
import de.danoeh.antennapod.core.preferences.UserPreferences;
public class NetworkUtils {
private static final String TAG = "NetworkUtils";
@ -66,4 +67,18 @@ public class NetworkUtils {
NetworkInfo info = cm.getActiveNetworkInfo();
return info != null && info.isConnected();
}
public static boolean isDownloadAllowed(Context context) {
return UserPreferences.isAllowMobileUpdate() || NetworkUtils.connectedToWifi(context);
}
public static boolean connectedToWifi(Context context) {
ConnectivityManager connManager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo mWifi = connManager
.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
return mWifi.isConnected();
}
}

View File

@ -104,6 +104,7 @@
<string name="mark_unread_label">Mark as unplayed</string>
<string name="marked_as_read_label">Marked as played</string>
<string name="add_to_queue_label">Add to Queue</string>
<string name="added_to_queue_label">Added to Queue</string>
<string name="remove_from_queue_label">Remove from Queue</string>
<string name="visit_website_label">Visit Website</string>
<string name="support_label">Flattr this</string>
@ -145,6 +146,11 @@
<string name="download_request_error_dialog_message_prefix">An error occurred when trying to download the file:\u0020</string>
<string name="authentication_notification_title">Authentication required</string>
<string name="authentication_notification_msg">The resource you requested requires a username and a password</string>
<string name="confirm_mobile_download_dialog_title">Confirm Mobile Download</string>
<string name="confirm_mobile_download_dialog_message_not_in_queue">Downloading over mobile data connection is disabled in the settings.\n\nEnable temporarily or just add to queue?\n\n<small>Your choice will be remember for 10 minutes.</small></string>
<string name="confirm_mobile_download_dialog_message">Downloading over mobile data connection is disabled in the settings.\n\nEnable temporarily?\n\n<small>Your choice will be remember for 10 minutes.</small></string>
<string name="confirm_mobile_download_dialog_only_add_to_queue">Only add to Queue</string>
<string name="confirm_mobile_download_dialog_enable_temporarily">Enable temporarily</string>
<!-- Mediaplayer messages -->
<string name="player_error_msg">Error!</string>