Android Open Source - Viz Download Task






From Project

Back to project page Viz.

License

The source code is released under:

GNU General Public License

If you think the Android project Viz listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*
 * Copyright 2012-2014, First Three LLC//from  w w  w  .java 2s  .c om
 *
 * This file is a part of Viz.
 *
 * Viz is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published
 * by the Free Software Foundation, either version 3 of the License,
 * or (at your option) any later version.
 *
 * Viz is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Viz.  If not, see <http://www.gnu.org/licenses/>.
 */

package com.first3.viz.utils;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.InputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

import android.content.ContentValues;
import android.net.Uri;
import android.os.AsyncTask;

import com.first3.viz.R;
import com.first3.viz.VizApp;
import com.first3.viz.download.DownloadManager.ProgressListener;
import com.first3.viz.models.Resource;
import com.first3.viz.provider.VizContract;

public class DownloadTask extends AsyncTask<Resource, Integer, Boolean> {
    private Resource mResource;
    private Uri mUri;
    private ProgressListener mListener;
    private int mProgress = 0;
    private String mFailure;
    private static int MAX_BUF_SIZE = 1024 * 4;
    private volatile long mCurrentFilesize = 0;

    public DownloadTask(ProgressListener listener) {
        super();
        mListener = listener;
    }

    public AsyncTask<Resource, Integer, Boolean> run(Resource...param ) {
        if (Utils.isHoneycombOrHigher()) {
            //@TargetApi(11)
            return executeOnExecutor(THREAD_POOL_EXECUTOR, param);
        } else {
            return execute(param);
        }
    }

    @Override
    protected Boolean doInBackground(Resource... params) {
        mResource = params[0];
        mUri = mResource.getDownloadUri();
        try {
            return download();
        } catch (Exception e) {
            Log.w("Download failed: " + e.getLocalizedMessage());
            mFailure = e.getLocalizedMessage();
            return false;
        }
    }

    public String getFailureText() {
        return mFailure;
    }

    /**
     * Returns true if the download was successful.  Throws an IOException
     * if there was an unforseen error.  Returns false if the download was
     * interrupted by the user.
     */
    private boolean download() throws IOException {
        URL url = null;

        long localFileSize = mResource.getFilesizeOnDisk();
        mCurrentFilesize = localFileSize;

        try {
            url = new URL(mResource.getURL());
        } catch (MalformedURLException e) {
            Log.d("malformed url: " + mResource.getURL());
            throw e;
        }

        HttpURLConnection urlConnection = null;
        try {
            urlConnection = (HttpURLConnection) url.openConnection();
        } catch (IOException e) {
            Log.d("Could not open connection error");
            throw e;
        }

        urlConnection.setConnectTimeout(5000);
        // handle connection establishment error, timeout, etc

        if (localFileSize > 0) {
            urlConnection.setRequestProperty("Range", "bytes=" + localFileSize + "-");

            String lastModified = mResource.getURLLastModified();
            urlConnection.setRequestProperty("If-Range", lastModified);
            Log.d("Saved Last-Modified URL header: "+lastModified);

            // Check to see that the server honored the range request
            String rangeConfirmation = urlConnection.getHeaderField("Content-Range");
            if (rangeConfirmation==null || rangeConfirmation.startsWith("0-")) {
                Log.d("Resume is not supported by the server");
                mResource.deleteFile();
                localFileSize = mCurrentFilesize = 0;
            } else {
                Log.d("Range confirmation: " + rangeConfirmation);
            }
        } else {
            String lastModified = urlConnection.getHeaderField("Last-Modified");
            // Is there a method for this?
            ContentValues map = new ContentValues();
            map.put(VizContract.Downloads.URL_LASTMODIFIED, lastModified);
            VizApp.getResolver().update(mUri, map, null, null);
        }

        urlConnection.connect();

        String sLength = urlConnection.getHeaderField("Content-Length");
        if (sLength == null) {
            throw new IOException(VizApp.getResString(R.string.download_error_content_length) + ": " +
                    mResource.getURL());
        }

        long fileSizeRemaining = Long.parseLong(sLength);
        float bytesAvailable = Utils.bytesAvailable(mResource.getDownloadDirectory());
        if (fileSizeRemaining == 0) {
            Log.w("Got 0 file size from Content-Length header");
            fileSizeRemaining = 1024*1024*20;
        } else {
            Log.d("remaining to download: " + fileSizeRemaining);
            Log.d("already downloaded: " + localFileSize);
            Log.d("available space: " + bytesAvailable);
            if (fileSizeRemaining > bytesAvailable) {
                String requested = String.format("%.2f", (fileSizeRemaining / (1024.f * 1024.f)));
                String available = String.format("%.2f", (bytesAvailable / (1024.f * 1024.f)));
                throw new IOException(VizApp.getResString(R.string.download_error_nofreespace, requested, available));
            }
        }

        mListener.onFilesizeUpdate(mResource, fileSizeRemaining+localFileSize);

        int bufferSize = 1024*100*2;
        InputStream in = new BufferedInputStream(urlConnection.getInputStream(), bufferSize);

        // TODO: figure out how to go through content resolver
        OutputStream ostream = mResource.getOutputFileStream(true);

        BufferedOutputStream bout = null;
        try {
            bout = new BufferedOutputStream(ostream, bufferSize);
            int len = 0;
            int chunkSize = Long.valueOf(localFileSize+fileSizeRemaining).intValue() / VizContract.Downloads.PROGRESS_MAX_NUM;
            byte[] buffer = new byte[MAX_BUF_SIZE];
            Integer progress = (int) (localFileSize/chunkSize);
            int chunker = 0;

            while ((len = in.read(buffer, 0, MAX_BUF_SIZE)) !=-1) {
                chunker += len;
                bout.write(buffer, 0, len);
                mCurrentFilesize += len;

                if (isCancelled()) {
                    Log.d("isCancelled(uri=" + mUri + ")");

                    // 4.0+ works and 2.3.6 fails. Romain said it was fixed in froyo+.
                    if (Utils.isLowerThanHoneyComb()) {
                        // cancel broken in older builds.  Romain says fixed in Froyo+
                        Log.d("calling onCancelled manually");
                        onCancelled(true);
                    }
                    return false;
                }

                if (chunker >= chunkSize) {
                    progress += 1;
                    chunker = 0;
                    publishProgress(progress);
                }
                if (len == -1) {
                    progress = VizContract.Downloads.PROGRESS_MAX_NUM;
                    publishProgress(progress);
                }
            }
        } finally {
            IOUtilities.closeStream(bout);
            IOUtilities.closeStream(in);
            IOUtilities.closeStream(ostream);
            urlConnection.disconnect();
        }
        return true;
    }

    // Called on the UI thread, triggered by a call to publishProgress
    @Override
    protected void onProgressUpdate(Integer... values) {
        super.onProgressUpdate(values);
        mProgress =+ values[0];
        mListener.onProgressUpdate(mResource, mProgress, mCurrentFilesize);
    }

    @Override
    protected void onCancelled(Boolean b) {
        Log.d("(b=" + b + ")");
        mListener.onCancelled(mResource);
    }

    // Runs on the UI thread before doInBackground(Params...)
    @Override
    protected void onPreExecute() {
    }

    // On UI thread after task has completed
    @Override
    protected void onPostExecute(Boolean success) {
        Log.d("onPostExecute(uri=" + mUri + ", success=" + success + ")");
        mListener.onFinish(mResource, success);
    }
}




Java Source Code List

com.actionbarsherlock.BuildConfig.java
com.first3.viz.Config.java
com.first3.viz.Config.java
com.first3.viz.Constants.java
com.first3.viz.Preferences.java
com.first3.viz.VersionChangeNotifier.java
com.first3.viz.VizApp.java
com.first3.viz.browser.Browser.java
com.first3.viz.browser.VizWebChromeClient.java
com.first3.viz.browser.VizWebViewClient.java
com.first3.viz.builders.BlinkxResourceBuilder.java
com.first3.viz.builders.CombinedResourceBuilder.java
com.first3.viz.builders.ContainerResourceBuilder.java
com.first3.viz.builders.DailyMotionResourceBuilder.java
com.first3.viz.builders.FlashPlayerResourceBuilder.java
com.first3.viz.builders.FunnyOrDieResourceBuilder.java
com.first3.viz.builders.GenericResourceBuilder.java
com.first3.viz.builders.GoGoAnimeResourceBuilder.java
com.first3.viz.builders.JSResourceBuilder.java
com.first3.viz.builders.LiveleakResourceBuilder.java
com.first3.viz.builders.MetacafeResourceBuilder.java
com.first3.viz.builders.NovamovResourceBuilder.java
com.first3.viz.builders.Play44ResourceBuilder.java
com.first3.viz.builders.PornHubBuilder.java
com.first3.viz.builders.RedtubeBuilder.java
com.first3.viz.builders.ResourceBuilder.java
com.first3.viz.builders.VevoResourceBuilder.java
com.first3.viz.builders.Video44ResourceBuilder.java
com.first3.viz.builders.VideoFunResourceBuilder.java
com.first3.viz.builders.VidzurResourceBuilder.java
com.first3.viz.builders.VimeoResourceBuilder.java
com.first3.viz.builders.YouruploadResourceBuilder.java
com.first3.viz.content.ContentSource.java
com.first3.viz.content.ContentSources.java
com.first3.viz.content.ContentType.java
com.first3.viz.content.ContentTypes.java
com.first3.viz.download.Container.java
com.first3.viz.download.DownloadManager.java
com.first3.viz.download.StringContainer.java
com.first3.viz.models.Favorite.java
com.first3.viz.models.Resource.java
com.first3.viz.players.VideoPlayer.java
com.first3.viz.provider.VizContract.java
com.first3.viz.provider.VizDatabase.java
com.first3.viz.provider.VizProvider.java
com.first3.viz.ui.ActivityDelegate.java
com.first3.viz.ui.DirectoryListAdapter.java
com.first3.viz.ui.DownloadDirectoryDialogPreference.java
com.first3.viz.ui.Downloads.java
com.first3.viz.ui.FastBitmapDrawable.java
com.first3.viz.ui.Favorites.java
com.first3.viz.ui.FileManager.java
com.first3.viz.ui.PinSelectorDialogFragment.java
com.first3.viz.ui.ProgressDialogFragment.java
com.first3.viz.ui.Settings.java
com.first3.viz.ui.VizMediaPlayer.java
com.first3.viz.utils.AbstractPauseHandler.java
com.first3.viz.utils.ActivityParent.java
com.first3.viz.utils.DownloadTask.java
com.first3.viz.utils.FetchContainerTask.java
com.first3.viz.utils.FragmentParent.java
com.first3.viz.utils.IOUtilities.java
com.first3.viz.utils.ImageUtilities.java
com.first3.viz.utils.Lists.java
com.first3.viz.utils.Log.java
com.first3.viz.utils.Maps.java
com.first3.viz.utils.SelectionBuilder.java
com.first3.viz.utils.StringBuffer.java
com.first3.viz.utils.TabsAdapter.java
com.first3.viz.utils.Utils.java
com.first3.viz.utils.VizUtils.java