New MP4 muxer + Queue changes + Storage fixes
Main changes: * correctly check the available space (CircularFile.java) * misc cleanup (CircularFile.java) * use the "Error Reporter" for non-http errors * rewrite network state checking and add better support for API 21 (Lollipop) or higher * implement "metered networks" * add buttons in "Downloads" activity to start/pause all pending downloads, ignoring the queue flag or if the network is "metered" * add workaround for VPN connections and/or network switching. Example: switching WiFi to 3G * rewrite DataReader ¡Webm muxer is now 57% more faster! * rewrite CircularFile, use file buffers instead of memory buffers. Less troubles in low-end devices * fix missing offset for KaxCluster (WebMWriter.java), manifested as no thumbnails on file explorers Download queue: * remember queue status, unless the user pause the download (un-queue) * semi-automatic downloads, between networks. Effective if the user create a new download or the downloads activity is starts * allow enqueue failed downloads * new option, queue limit, enabled by default. Used to allow one or multiple downloads at same time Miscellaneous: * fix crash while selecting details/error menu (mistake on MissionFragment.java) * misc serialize changes (DownloadMission.java) * minor UI tweaks * allow overwrite paused downloads * fix wrong icons for grid/list button in downloads * add share option * implement #2006 * correct misspelled word in strings.xml (es) (cmn) * fix MissionAdapter crash during device shutdown New Mp4Muxer + required changes: * new mp4 muxer (from dash only) with this, muxing on Android 7 is possible now!!! * re-work in SharpStream * drop mp4 dash muxer * misc changes: add warning in SecondaryStreamHelper.java, * strip m4a DASH files to normal m4a format (youtube only) Fix storage issues: * warn to the user if is choosing a "read only" download directory (for external SD Cards), useless is rooted :) * "write proof" allow post-processing resuming only if the device ran out of space * implement "insufficient storage" error for downloads
This commit is contained in:
parent
b19caad970
commit
8d8059229f
49 changed files with 2715 additions and 1936 deletions
|
|
@ -14,15 +14,17 @@ import android.os.Looper;
|
|||
import android.os.Message;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.StringRes;
|
||||
import android.support.v4.content.FileProvider;
|
||||
import android.support.v4.view.ViewCompat;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.support.v7.util.DiffUtil;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.support.v7.widget.RecyclerView.ViewHolder;
|
||||
import android.support.v7.widget.RecyclerView.Adapter;
|
||||
import android.support.v7.widget.RecyclerView.ViewHolder;
|
||||
import android.util.Log;
|
||||
import android.util.SparseArray;
|
||||
import android.view.HapticFeedbackConstants;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
|
|
@ -36,14 +38,17 @@ import android.widget.Toast;
|
|||
|
||||
import org.schabi.newpipe.BuildConfig;
|
||||
import org.schabi.newpipe.R;
|
||||
import org.schabi.newpipe.report.ErrorActivity;
|
||||
import org.schabi.newpipe.report.UserAction;
|
||||
import org.schabi.newpipe.util.NavigationHelper;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
|
||||
import us.shandian.giga.get.DownloadMission;
|
||||
import us.shandian.giga.get.FinishedMission;
|
||||
import us.shandian.giga.get.Mission;
|
||||
import us.shandian.giga.service.DownloadManager;
|
||||
import us.shandian.giga.service.DownloadManagerService;
|
||||
import us.shandian.giga.ui.common.Deleter;
|
||||
|
|
@ -57,10 +62,13 @@ import static us.shandian.giga.get.DownloadMission.ERROR_CONNECT_HOST;
|
|||
import static us.shandian.giga.get.DownloadMission.ERROR_FILE_CREATION;
|
||||
import static us.shandian.giga.get.DownloadMission.ERROR_HTTP_NO_CONTENT;
|
||||
import static us.shandian.giga.get.DownloadMission.ERROR_HTTP_UNSUPPORTED_RANGE;
|
||||
import static us.shandian.giga.get.DownloadMission.ERROR_INSUFFICIENT_STORAGE;
|
||||
import static us.shandian.giga.get.DownloadMission.ERROR_NOTHING;
|
||||
import static us.shandian.giga.get.DownloadMission.ERROR_PATH_CREATION;
|
||||
import static us.shandian.giga.get.DownloadMission.ERROR_PERMISSION_DENIED;
|
||||
import static us.shandian.giga.get.DownloadMission.ERROR_POSTPROCESSING;
|
||||
import static us.shandian.giga.get.DownloadMission.ERROR_POSTPROCESSING_HOLD;
|
||||
import static us.shandian.giga.get.DownloadMission.ERROR_POSTPROCESSING_STOPPED;
|
||||
import static us.shandian.giga.get.DownloadMission.ERROR_SSL_EXCEPTION;
|
||||
import static us.shandian.giga.get.DownloadMission.ERROR_UNKNOWN_EXCEPTION;
|
||||
import static us.shandian.giga.get.DownloadMission.ERROR_UNKNOWN_HOST;
|
||||
|
|
@ -69,6 +77,7 @@ public class MissionAdapter extends Adapter<ViewHolder> {
|
|||
private static final SparseArray<String> ALGORITHMS = new SparseArray<>();
|
||||
private static final String TAG = "MissionAdapter";
|
||||
private static final String UNDEFINED_PROGRESS = "--.-%";
|
||||
private static final String DEFAULT_MIME_TYPE = "*/*";
|
||||
|
||||
|
||||
static {
|
||||
|
|
@ -85,9 +94,11 @@ public class MissionAdapter extends Adapter<ViewHolder> {
|
|||
private ArrayList<ViewHolderItem> mPendingDownloadsItems = new ArrayList<>();
|
||||
private Handler mHandler;
|
||||
private MenuItem mClear;
|
||||
private MenuItem mStartButton;
|
||||
private MenuItem mPauseButton;
|
||||
private View mEmptyMessage;
|
||||
|
||||
public MissionAdapter(Context context, DownloadManager downloadManager, MenuItem clearButton, View emptyMessage) {
|
||||
public MissionAdapter(Context context, DownloadManager downloadManager, View emptyMessage) {
|
||||
mContext = context;
|
||||
mDownloadManager = downloadManager;
|
||||
mDeleter = null;
|
||||
|
|
@ -105,10 +116,18 @@ public class MissionAdapter extends Adapter<ViewHolder> {
|
|||
onServiceMessage(msg);
|
||||
break;
|
||||
}
|
||||
|
||||
if (mStartButton != null && mPauseButton != null) switch (msg.what) {
|
||||
case DownloadManagerService.MESSAGE_DELETED:
|
||||
case DownloadManagerService.MESSAGE_ERROR:
|
||||
case DownloadManagerService.MESSAGE_FINISHED:
|
||||
case DownloadManagerService.MESSAGE_PAUSED:
|
||||
checkMasterButtonsVisibility();
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
mClear = clearButton;
|
||||
mEmptyMessage = emptyMessage;
|
||||
|
||||
mIterator = downloadManager.getIterator();
|
||||
|
|
@ -225,8 +244,10 @@ public class MissionAdapter extends Adapter<ViewHolder> {
|
|||
long deltaDone = mission.done - h.lastDone;
|
||||
boolean hasError = mission.errCode != ERROR_NOTHING;
|
||||
|
||||
// on error hide marquee or show if condition (mission.done < 1 || mission.unknownLength) is true
|
||||
h.progress.setMarquee(!hasError && (mission.done < 1 || mission.unknownLength));
|
||||
// hide on error
|
||||
// show if current resource length is not fetched
|
||||
// show if length is unknown
|
||||
h.progress.setMarquee(!hasError && (!mission.isInitialized() || mission.unknownLength));
|
||||
|
||||
float progress;
|
||||
if (mission.unknownLength) {
|
||||
|
|
@ -305,36 +326,64 @@ public class MissionAdapter extends Adapter<ViewHolder> {
|
|||
}
|
||||
}
|
||||
|
||||
private boolean viewWithFileProvider(@NonNull File file) {
|
||||
if (!file.exists()) return true;
|
||||
private void viewWithFileProvider(Mission mission) {
|
||||
if (checkInvalidFile(mission)) return;
|
||||
|
||||
String ext = Utility.getFileExt(file.getName());
|
||||
if (ext == null) return false;
|
||||
String mimeType = resolveMimeType(mission);
|
||||
|
||||
String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(ext.substring(1));
|
||||
Log.v(TAG, "Mime: " + mimeType + " package: " + BuildConfig.APPLICATION_ID + ".provider");
|
||||
if (BuildConfig.DEBUG)
|
||||
Log.v(TAG, "Mime: " + mimeType + " package: " + BuildConfig.APPLICATION_ID + ".provider");
|
||||
|
||||
Uri uri = FileProvider.getUriForFile(mContext, BuildConfig.APPLICATION_ID + ".provider", file);
|
||||
Uri uri = FileProvider.getUriForFile(
|
||||
mContext,
|
||||
BuildConfig.APPLICATION_ID + ".provider",
|
||||
mission.getDownloadedFile()
|
||||
);
|
||||
|
||||
Intent intent = new Intent();
|
||||
intent.setAction(Intent.ACTION_VIEW);
|
||||
intent.setDataAndType(uri, mimeType);
|
||||
intent.addFlags(FLAG_GRANT_READ_URI_PERMISSION);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
intent.addFlags(FLAG_GRANT_PREFIX_URI_PERMISSION);
|
||||
}
|
||||
if(Build.VERSION.SDK_INT <= Build.VERSION_CODES.M) {
|
||||
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.M) {
|
||||
intent.addFlags(FLAG_ACTIVITY_NEW_TASK);
|
||||
}
|
||||
|
||||
//mContext.grantUriPermission(packageName, uri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||
Log.v(TAG, "Starting intent: " + intent);
|
||||
|
||||
if (intent.resolveActivity(mContext.getPackageManager()) != null) {
|
||||
mContext.startActivity(intent);
|
||||
} else {
|
||||
Toast noPlayerToast = Toast.makeText(mContext, R.string.toast_no_player, Toast.LENGTH_LONG);
|
||||
noPlayerToast.show();
|
||||
Toast.makeText(mContext, R.string.toast_no_player, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
|
||||
private void shareFile(Mission mission) {
|
||||
if (checkInvalidFile(mission)) return;
|
||||
|
||||
Intent intent = new Intent(Intent.ACTION_SEND);
|
||||
intent.setType(resolveMimeType(mission));
|
||||
intent.putExtra(Intent.EXTRA_STREAM, mission.getDownloadedFile().toURI());
|
||||
|
||||
mContext.startActivity(Intent.createChooser(intent, null));
|
||||
}
|
||||
|
||||
private static String resolveMimeType(@NonNull Mission mission) {
|
||||
String ext = Utility.getFileExt(mission.getDownloadedFile().getName());
|
||||
if (ext == null) return DEFAULT_MIME_TYPE;
|
||||
|
||||
String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(ext.substring(1));
|
||||
|
||||
return mimeType == null ? DEFAULT_MIME_TYPE : mimeType;
|
||||
}
|
||||
|
||||
private boolean checkInvalidFile(@NonNull Mission mission) {
|
||||
if (mission.getDownloadedFile().exists()) return false;
|
||||
|
||||
Toast.makeText(mContext, R.string.missing_file, Toast.LENGTH_SHORT).show();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -343,15 +392,9 @@ public class MissionAdapter extends Adapter<ViewHolder> {
|
|||
}
|
||||
|
||||
private void onServiceMessage(@NonNull Message msg) {
|
||||
switch (msg.what) {
|
||||
case DownloadManagerService.MESSAGE_PROGRESS:
|
||||
setAutoRefresh(true);
|
||||
return;
|
||||
case DownloadManagerService.MESSAGE_ERROR:
|
||||
case DownloadManagerService.MESSAGE_FINISHED:
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
if (msg.what == DownloadManagerService.MESSAGE_PROGRESS) {
|
||||
setAutoRefresh(true);
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < mPendingDownloadsItems.size(); i++) {
|
||||
|
|
@ -370,74 +413,98 @@ public class MissionAdapter extends Adapter<ViewHolder> {
|
|||
}
|
||||
|
||||
private void showError(@NonNull DownloadMission mission) {
|
||||
StringBuilder str = new StringBuilder();
|
||||
str.append(mContext.getString(R.string.label_code));
|
||||
str.append(": ");
|
||||
str.append(mission.errCode);
|
||||
str.append('\n');
|
||||
@StringRes int msg = R.string.general_error;
|
||||
String msgEx = null;
|
||||
|
||||
switch (mission.errCode) {
|
||||
case 416:
|
||||
str.append(mContext.getString(R.string.error_http_requested_range_not_satisfiable));
|
||||
msg = R.string.error_http_requested_range_not_satisfiable;
|
||||
break;
|
||||
case 404:
|
||||
str.append(mContext.getString(R.string.error_http_not_found));
|
||||
msg = R.string.error_http_not_found;
|
||||
break;
|
||||
case ERROR_NOTHING:
|
||||
str.append("¿?");
|
||||
break;
|
||||
return;// this never should happen
|
||||
case ERROR_FILE_CREATION:
|
||||
str.append(mContext.getString(R.string.error_file_creation));
|
||||
msg = R.string.error_file_creation;
|
||||
break;
|
||||
case ERROR_HTTP_NO_CONTENT:
|
||||
str.append(mContext.getString(R.string.error_http_no_content));
|
||||
msg = R.string.error_http_no_content;
|
||||
break;
|
||||
case ERROR_HTTP_UNSUPPORTED_RANGE:
|
||||
str.append(mContext.getString(R.string.error_http_unsupported_range));
|
||||
msg = R.string.error_http_unsupported_range;
|
||||
break;
|
||||
case ERROR_PATH_CREATION:
|
||||
str.append(mContext.getString(R.string.error_path_creation));
|
||||
msg = R.string.error_path_creation;
|
||||
break;
|
||||
case ERROR_PERMISSION_DENIED:
|
||||
str.append(mContext.getString(R.string.permission_denied));
|
||||
msg = R.string.permission_denied;
|
||||
break;
|
||||
case ERROR_SSL_EXCEPTION:
|
||||
str.append(mContext.getString(R.string.error_ssl_exception));
|
||||
msg = R.string.error_ssl_exception;
|
||||
break;
|
||||
case ERROR_UNKNOWN_HOST:
|
||||
str.append(mContext.getString(R.string.error_unknown_host));
|
||||
msg = R.string.error_unknown_host;
|
||||
break;
|
||||
case ERROR_CONNECT_HOST:
|
||||
str.append(mContext.getString(R.string.error_connect_host));
|
||||
msg = R.string.error_connect_host;
|
||||
break;
|
||||
case ERROR_POSTPROCESSING_STOPPED:
|
||||
msg = R.string.error_postprocessing_stopped;
|
||||
break;
|
||||
case ERROR_POSTPROCESSING:
|
||||
str.append(mContext.getString(R.string.error_postprocessing_failed));
|
||||
case ERROR_UNKNOWN_EXCEPTION:
|
||||
case ERROR_POSTPROCESSING_HOLD:
|
||||
showError(mission.errObject, UserAction.DOWNLOAD_POSTPROCESSING, R.string.error_postprocessing_failed);
|
||||
return;
|
||||
case ERROR_INSUFFICIENT_STORAGE:
|
||||
msg = R.string.error_insufficient_storage;
|
||||
break;
|
||||
case ERROR_UNKNOWN_EXCEPTION:
|
||||
showError(mission.errObject, UserAction.DOWNLOAD_FAILED, R.string.general_error);
|
||||
return;
|
||||
default:
|
||||
if (mission.errCode >= 100 && mission.errCode < 600) {
|
||||
str = new StringBuilder(8);
|
||||
str.append("HTTP ");
|
||||
str.append(mission.errCode);
|
||||
msgEx = "HTTP " + mission.errCode;
|
||||
} else if (mission.errObject == null) {
|
||||
str.append("(not_decelerated_error_code)");
|
||||
msgEx = "(not_decelerated_error_code)";
|
||||
} else {
|
||||
showError(mission.errObject, UserAction.DOWNLOAD_FAILED, msg);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (mission.errObject != null) {
|
||||
str.append("\n\n");
|
||||
str.append(mission.errObject.toString());
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
|
||||
|
||||
if (msgEx != null)
|
||||
builder.setMessage(msgEx);
|
||||
else
|
||||
builder.setMessage(msg);
|
||||
|
||||
// add report button for non-HTTP errors (range 100-599)
|
||||
if (mission.errObject != null && (mission.errCode < 100 || mission.errCode >= 600)) {
|
||||
@StringRes final int mMsg = msg;
|
||||
builder.setPositiveButton(R.string.error_report_title, (dialog, which) ->
|
||||
showError(mission.errObject, UserAction.DOWNLOAD_FAILED, mMsg)
|
||||
);
|
||||
}
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
|
||||
builder.setTitle(mission.name)
|
||||
.setMessage(str)
|
||||
.setNegativeButton(android.R.string.ok, (dialog, which) -> dialog.cancel())
|
||||
builder.setNegativeButton(android.R.string.ok, (dialog, which) -> dialog.cancel())
|
||||
.setTitle(mission.name)
|
||||
.create()
|
||||
.show();
|
||||
}
|
||||
|
||||
private void showError(Exception exception, UserAction action, @StringRes int reason) {
|
||||
ErrorActivity.reportError(
|
||||
mContext,
|
||||
Collections.singletonList(exception),
|
||||
null,
|
||||
null,
|
||||
ErrorActivity.ErrorInfo.make(action, "-", "-", reason)
|
||||
);
|
||||
}
|
||||
|
||||
public void clearFinishedDownloads() {
|
||||
mDownloadManager.forgetFinishedDownloads();
|
||||
applyChanges();
|
||||
|
|
@ -466,16 +533,24 @@ public class MissionAdapter extends Adapter<ViewHolder> {
|
|||
showError(mission);
|
||||
return true;
|
||||
case R.id.queue:
|
||||
h.queue.setChecked(!h.queue.isChecked());
|
||||
mission.enqueued = h.queue.isChecked();
|
||||
boolean flag = !h.queue.isChecked();
|
||||
h.queue.setChecked(flag);
|
||||
mission.setEnqueued(flag);
|
||||
updateProgress(h);
|
||||
return true;
|
||||
case R.id.retry:
|
||||
mission.psContinue(true);
|
||||
return true;
|
||||
case R.id.cancel:
|
||||
mission.psContinue(false);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
switch (id) {
|
||||
case R.id.open:
|
||||
return viewWithFileProvider(h.item.mission.getDownloadedFile());
|
||||
case R.id.menu_item_share:
|
||||
shareFile(h.item.mission);
|
||||
return true;
|
||||
case R.id.delete:
|
||||
if (mDeleter == null) {
|
||||
mDownloadManager.deleteMission(h.item.mission);
|
||||
|
|
@ -529,15 +604,42 @@ public class MissionAdapter extends Adapter<ViewHolder> {
|
|||
}
|
||||
|
||||
public void setClearButton(MenuItem clearButton) {
|
||||
if (mClear == null) clearButton.setVisible(mIterator.hasFinishedMissions());
|
||||
if (mClear == null)
|
||||
clearButton.setVisible(mIterator.hasFinishedMissions());
|
||||
|
||||
mClear = clearButton;
|
||||
}
|
||||
|
||||
public void setMasterButtons(MenuItem startButton, MenuItem pauseButton) {
|
||||
boolean init = mStartButton == null || mPauseButton == null;
|
||||
|
||||
mStartButton = startButton;
|
||||
mPauseButton = pauseButton;
|
||||
|
||||
if (init) checkMasterButtonsVisibility();
|
||||
}
|
||||
|
||||
private void checkEmptyMessageVisibility() {
|
||||
int flag = mIterator.getOldListSize() > 0 ? View.GONE : View.VISIBLE;
|
||||
if (mEmptyMessage.getVisibility() != flag) mEmptyMessage.setVisibility(flag);
|
||||
}
|
||||
|
||||
private void checkMasterButtonsVisibility() {
|
||||
boolean[] state = mIterator.hasValidPendingMissions();
|
||||
|
||||
mStartButton.setVisible(state[0]);
|
||||
mPauseButton.setVisible(state[1]);
|
||||
}
|
||||
|
||||
public void ensurePausedMissions() {
|
||||
for (ViewHolderItem h : mPendingDownloadsItems) {
|
||||
if (((DownloadMission) h.item.mission).running) continue;
|
||||
updateProgress(h);
|
||||
h.lastTimeStamp = -1;
|
||||
h.lastDone = -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void deleterDispose(Bundle bundle) {
|
||||
if (mDeleter != null) mDeleter.dispose(bundle);
|
||||
|
|
@ -604,6 +706,8 @@ public class MissionAdapter extends Adapter<ViewHolder> {
|
|||
ProgressDrawable progress;
|
||||
|
||||
PopupMenu popupMenu;
|
||||
MenuItem retry;
|
||||
MenuItem cancel;
|
||||
MenuItem start;
|
||||
MenuItem pause;
|
||||
MenuItem open;
|
||||
|
|
@ -636,22 +740,34 @@ public class MissionAdapter extends Adapter<ViewHolder> {
|
|||
button.setOnClickListener(v -> showPopupMenu());
|
||||
|
||||
Menu menu = popupMenu.getMenu();
|
||||
retry = menu.findItem(R.id.retry);
|
||||
cancel = menu.findItem(R.id.cancel);
|
||||
start = menu.findItem(R.id.start);
|
||||
pause = menu.findItem(R.id.pause);
|
||||
open = menu.findItem(R.id.open);
|
||||
open = menu.findItem(R.id.menu_item_share);
|
||||
queue = menu.findItem(R.id.queue);
|
||||
showError = menu.findItem(R.id.error_message_view);
|
||||
delete = menu.findItem(R.id.delete);
|
||||
source = menu.findItem(R.id.source);
|
||||
checksum = menu.findItem(R.id.checksum);
|
||||
|
||||
itemView.setOnClickListener((v) -> {
|
||||
itemView.setHapticFeedbackEnabled(true);
|
||||
|
||||
itemView.setOnClickListener(v -> {
|
||||
if (item.mission instanceof FinishedMission)
|
||||
viewWithFileProvider(item.mission.getDownloadedFile());
|
||||
viewWithFileProvider(item.mission);
|
||||
});
|
||||
|
||||
itemView.setOnLongClickListener(v -> {
|
||||
v.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
|
||||
showPopupMenu();
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
private void showPopupMenu() {
|
||||
retry.setVisible(false);
|
||||
cancel.setVisible(false);
|
||||
start.setVisible(false);
|
||||
pause.setVisible(false);
|
||||
open.setVisible(false);
|
||||
|
|
@ -664,7 +780,16 @@ public class MissionAdapter extends Adapter<ViewHolder> {
|
|||
DownloadMission mission = item.mission instanceof DownloadMission ? (DownloadMission) item.mission : null;
|
||||
|
||||
if (mission != null) {
|
||||
if (!mission.isPsRunning()) {
|
||||
if (mission.isPsRunning()) {
|
||||
switch (mission.errCode) {
|
||||
case ERROR_INSUFFICIENT_STORAGE:
|
||||
case ERROR_POSTPROCESSING_HOLD:
|
||||
retry.setVisible(true);
|
||||
cancel.setVisible(true);
|
||||
showError.setVisible(true);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (mission.running) {
|
||||
pause.setVisible(true);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -35,6 +35,8 @@ public class MissionsFragment extends Fragment {
|
|||
private boolean mLinear;
|
||||
private MenuItem mSwitch;
|
||||
private MenuItem mClear = null;
|
||||
private MenuItem mStart = null;
|
||||
private MenuItem mPause = null;
|
||||
|
||||
private RecyclerView mList;
|
||||
private View mEmpty;
|
||||
|
|
@ -54,9 +56,11 @@ public class MissionsFragment extends Fragment {
|
|||
mBinder = (DownloadManagerService.DMBinder) binder;
|
||||
mBinder.clearDownloadNotifications();
|
||||
|
||||
mAdapter = new MissionAdapter(mContext, mBinder.getDownloadManager(), mClear, mEmpty);
|
||||
mAdapter = new MissionAdapter(mContext, mBinder.getDownloadManager(), mEmpty);
|
||||
mAdapter.deleterLoad(mBundle, getView());
|
||||
|
||||
setAdapterButtons();
|
||||
|
||||
mBundle = null;
|
||||
|
||||
mBinder.addMissionEventListener(mAdapter.getMessenger());
|
||||
|
|
@ -132,7 +136,7 @@ public class MissionsFragment extends Fragment {
|
|||
public void onAttach(Activity activity) {
|
||||
super.onAttach(activity);
|
||||
|
||||
mContext = activity.getApplicationContext();
|
||||
mContext = activity;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -154,7 +158,11 @@ public class MissionsFragment extends Fragment {
|
|||
public void onPrepareOptionsMenu(Menu menu) {
|
||||
mSwitch = menu.findItem(R.id.switch_mode);
|
||||
mClear = menu.findItem(R.id.clear_list);
|
||||
if (mAdapter != null) mAdapter.setClearButton(mClear);
|
||||
mStart = menu.findItem(R.id.start_downloads);
|
||||
mPause = menu.findItem(R.id.pause_downloads);
|
||||
|
||||
if (mAdapter != null) setAdapterButtons();
|
||||
|
||||
super.onPrepareOptionsMenu(menu);
|
||||
}
|
||||
|
||||
|
|
@ -168,6 +176,14 @@ public class MissionsFragment extends Fragment {
|
|||
case R.id.clear_list:
|
||||
mAdapter.clearFinishedDownloads();
|
||||
return true;
|
||||
case R.id.start_downloads:
|
||||
item.setVisible(false);
|
||||
mBinder.getDownloadManager().startAllMissions();
|
||||
return true;
|
||||
case R.id.pause_downloads:
|
||||
item.setVisible(false);
|
||||
mBinder.getDownloadManager().pauseAllMissions(false);
|
||||
mAdapter.ensurePausedMissions();// update items view
|
||||
default:
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
|
@ -193,9 +209,9 @@ public class MissionsFragment extends Fragment {
|
|||
int icon;
|
||||
|
||||
if (mLinear)
|
||||
icon = isLight ? R.drawable.ic_list_black_24dp : R.drawable.ic_list_white_24dp;
|
||||
else
|
||||
icon = isLight ? R.drawable.ic_grid_black_24dp : R.drawable.ic_grid_white_24dp;
|
||||
else
|
||||
icon = isLight ? R.drawable.ic_list_black_24dp : R.drawable.ic_list_white_24dp;
|
||||
|
||||
mSwitch.setIcon(icon);
|
||||
mSwitch.setTitle(mLinear ? R.string.grid : R.string.list);
|
||||
|
|
@ -203,6 +219,13 @@ public class MissionsFragment extends Fragment {
|
|||
}
|
||||
}
|
||||
|
||||
private void setAdapterButtons() {
|
||||
if (mClear == null || mStart == null || mPause == null) return;
|
||||
|
||||
mAdapter.setClearButton(mClear);
|
||||
mAdapter.setMasterButtons(mStart, mPause);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue