package com.nuscomputing.ivle;
import java.io.File;
import com.nuscomputing.support.android.app.DownloadManager;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.DialogInterface.OnClickListener;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.support.v4.app.DialogFragment;
import android.text.format.Formatter;
import android.util.Log;
import android.view.ContextThemeWrapper;
import android.view.LayoutInflater;
import android.view.View;
import android.webkit.MimeTypeMap;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
/**
* Fragment used to display the current progress of downloading a file from
* the workbin.
* <p>
* @author yjwong
*/
public class WorkbinFileDownloadDialogFragment extends DialogFragment {
// {{{ properties
/** TAG for logging */
public static final String TAG = "WorkbinFileDownloadDialogFragment";
/** Instance of the alert dialog */
private AlertDialog mAlertDialog;
/** The file name */
private String mFileName;
/** The file size */
private Double mFileSize;
/** The download URL */
private Uri mDownloadUrl;
/** Is a download in progress? */
private boolean mDownloadInProgress;
/** The download manager */
private DownloadManager mDownloadManager;
/** This dialog fragment */
private DialogFragment mDialogFragment = this;
/** The download ID, returned by DownloadManager */
private long mDownloadId;
/** Should we monitor download status? */
private boolean mShouldMonitorStatus = true;
/** Check download status */
private Handler mHandler = new Handler();
private Runnable mDownloadStatusUpdater = new Runnable() {
@Override
public void run() {
// Query the download manager.
DownloadManager.Query query = new DownloadManager.Query();
query.setFilterById(mDownloadId);
Cursor cursor = mDownloadManager.query(query);
cursor.moveToFirst();
// Get the download status.
int status = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS));
Toast toast;
// After configuration change: wait a little while for the activity to return.
if (mDialogFragment.getActivity() == null) {
mHandler.postDelayed(mDownloadStatusUpdater, 250);
cursor.close();
return;
}
Context toastContext = mDialogFragment.getActivity().getApplicationContext();
switch (status) {
case DownloadManager.STATUS_FAILED:
mShouldMonitorStatus = false;
mDialogFragment.dismiss();
// Notify the user.
toast = Toast.makeText(toastContext, getString(R.string.workbin_file_download_dialog_fragment_unable_to_download), Toast.LENGTH_SHORT);
toast.show();
break;
case DownloadManager.STATUS_PAUSED:
mShouldMonitorStatus = false;
mDownloadManager.remove(mDownloadId);
mDialogFragment.dismiss();
// Notify the user.
toast = Toast.makeText(toastContext, getString(R.string.workbin_file_download_dialog_fragment_unable_to_download), Toast.LENGTH_SHORT);
toast.show();
break;
case DownloadManager.STATUS_PENDING:
// Hide the status.
TextView tvProgress = (TextView) mAlertDialog.findViewById(R.id.workbin_file_download_dialog_fragment_progress);
tvProgress.setText("");
tvProgress.setVisibility(View.GONE);
// Update the progress bar.
ProgressBar progressBar = (ProgressBar) mAlertDialog.findViewById(R.id.workbin_file_download_dialog_fragment_progress_bar);
progressBar.setIndeterminate(true);
// Update the file name.
TextView tvFileName = (TextView) mAlertDialog.findViewById(R.id.workbin_file_download_dialog_fragment_file_name);
tvFileName.setText(mFileName);
break;
case DownloadManager.STATUS_RUNNING:
// Obtain some download data.
Double bytesDownloaded = cursor.getDouble(cursor.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
Double totalBytes = mFileSize;
Double downloadPct = bytesDownloaded / totalBytes * 100;
// Format the arguments.
String bytesDownloadedStr = Formatter.formatFileSize(getActivity(), bytesDownloaded.intValue());
String totalBytesStr = Formatter.formatFileSize(getActivity(), totalBytes.intValue());
// Update the progress bar.
progressBar = (ProgressBar) mAlertDialog.findViewById(R.id.workbin_file_download_dialog_fragment_progress_bar);
progressBar.setMax(totalBytes.intValue());
progressBar.setProgress(bytesDownloaded.intValue());
progressBar.setIndeterminate(false);
// Update the bytes downloaded.
tvProgress = (TextView) mAlertDialog.findViewById(R.id.workbin_file_download_dialog_fragment_progress);
tvProgress.setText(getString(R.string.workbin_file_download_dialog_fragment_progress, bytesDownloadedStr, totalBytesStr, downloadPct.intValue()));
tvProgress.setVisibility(View.VISIBLE);
break;
case DownloadManager.STATUS_SUCCESSFUL:
mShouldMonitorStatus = false;
// Obtain the downloaded file location.
String localUri = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI));
Log.v(TAG, localUri);
if (localUri == null) {
break;
}
// Obtain the MIME type.
File downloadFile = new File(localUri);
MimeTypeMap mimeMap = MimeTypeMap.getSingleton();
String downloadFileExt = downloadFile.getName().substring(downloadFile.getName().indexOf(".") + 1).toLowerCase();
String mimeType = mimeMap.getMimeTypeFromExtension(downloadFileExt);
// Create the file open intent.
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.parse(localUri), mimeType);
// Try to open the file.
try {
startActivity(intent);
} catch (ActivityNotFoundException e) {
toast = Toast.makeText(toastContext,getString(R.string.workbin_file_download_dialog_fragment_no_app_found), Toast.LENGTH_SHORT);
toast.show();
}
mDialogFragment.dismiss();
break;
}
// Continue monitoring.
if (mShouldMonitorStatus) {
mHandler.postDelayed(mDownloadStatusUpdater, 250);
}
// Clean up.
cursor.close();
}
};
// }}}
// {{{ methods
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Additional fragment parameters.
this.setCancelable(false);
// Check if we're just returning.
if (savedInstanceState == null) {
savedInstanceState = new Bundle();
}
mDownloadInProgress = savedInstanceState.getBoolean("downloadInProgress", false);
if (mDownloadInProgress) {
mDownloadId = savedInstanceState.getLong("downloadId");
mDownloadUrl = Uri.parse(savedInstanceState.getString("downloadUrl"));
mFileName = savedInstanceState.getString("fileName");
mFileSize = savedInstanceState.getDouble("fileSize");
}
// Set up the dialog.
LayoutInflater inflater = (LayoutInflater) new ContextThemeWrapper(getActivity(), android.R.style.Theme_Holo_Light_Dialog).getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mAlertDialog = new AlertDialog.Builder(new ContextThemeWrapper(getActivity(), android.R.style.Theme_Holo_Light_Dialog))
.setNeutralButton("Hide", new onClickHideListener())
.setNegativeButton("Cancel", new onClickCancelListener())
.setView(inflater.inflate(R.layout.workbin_file_download_dialog_fragment, null))
.create();
return mAlertDialog;
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
// Save the state.
outState.putBoolean("downloadInProgress", mDownloadInProgress);
outState.putLong("downloadId", mDownloadId);
outState.putString("downloadUrl", mDownloadUrl.toString());
outState.putString("fileName", mFileName);
outState.putDouble("fileSize", mFileSize);
}
@Override
public void onResume() {
super.onResume();
// (Re)connect to download manager service.
mDownloadManager = new DownloadManager(getActivity().getContentResolver(), getClass().getPackage().getName());
if (mDownloadInProgress) {
// Resume the status updater.
mHandler.post(mDownloadStatusUpdater);
} else {
// Obtain the download URL.
Bundle args = getArguments();
mDownloadUrl = Uri.parse(args.getString("downloadUrl"));
mFileName = args.getString("fileName");
mFileSize = args.getDouble("fileSize");
startDownload();
}
}
@Override
public void onPause() {
super.onPause();
mHandler.removeCallbacksAndMessages(null);
}
private void startDownload() {
Log.v(TAG, "starting download of " + mDownloadUrl);
// Create a new download request.
DownloadManager.Request request = new DownloadManager.Request(mDownloadUrl);
// request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_HIDDEN);
request.setVisibleInDownloadsUi(false);
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, mFileName);
mDownloadId = mDownloadManager.enqueue(request);
mDownloadInProgress = true;
// Start monitoring the download status.
mHandler.post(mDownloadStatusUpdater);
}
// }}}
// {{{ classes
/**
* What happens when "Hide" is clicked?
* @author yjwong
*/
class onClickHideListener implements OnClickListener {
// {{{ methods
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
Log.v(TAG, "hide button clicked");
}
// }}}
}
/**
* What happens when "Cancel" is clicked?
* @author yjwong
*/
class onClickCancelListener implements OnClickListener {
// {{{ methods
@Override
public void onClick(DialogInterface dialog, int which) {
Log.v(TAG, "Download job " + mDownloadId + " cancelled by user");
mDownloadManager.remove(mDownloadId);
dialog.dismiss();
}
// }}}
}
// }}}
}