The best file downloader library for Android

Overview

Build Status Download Android Arsenal License

ScreenShot

Overview

Fetch is a simple, powerful, customizable file download manager library for Android.

ScreenShot

Features

  • Simple and easy to use API.
  • Continuous downloading in the background.
  • Concurrent downloading support.
  • Ability to pause and resume downloads.
  • Set the priority of a download.
  • Network-specific downloading support.
  • Ability to retry failed downloads.
  • Ability to group downloads.
  • Easy progress and status tracking.
  • Download remaining time reporting (ETA).
  • Download speed reporting.
  • Save and Retrieve download information anytime.
  • Notification Support.
  • Storage Access Framework, Content Provider and URI support.
  • And more...

Prerequisites

If you are saving downloads outside of your application's sandbox, you will need to add the following storage permissions to your application's manifest. For Android SDK version 23(M) and above, you will also need to explicitly request these permissions from the user.

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

Also, as you are going to use Internet to download files. We need to add the Internet access permissions in the Manifest.

<uses-permission android:name="android.permission.INTERNET"/>

How to use Fetch

Using Fetch is easy! Just add the Gradle dependency to your application's build.gradle file.

implementation "com.tonyodev.fetch2:fetch2:3.0.12"

Androidx use:

implementation "androidx.tonyodev.fetch2:xfetch2:3.1.6"

Next, get an instance of Fetch and request a download.

public class TestActivity extends AppCompatActivity {

    private Fetch fetch;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

 FetchConfiguration fetchConfiguration = new FetchConfiguration.Builder(this)
                .setDownloadConcurrentLimit(3)
                .build();

        fetch = Fetch.Impl.getInstance(fetchConfiguration);

        String url = "http:www.example.com/test.txt";
        String file = "/downloads/test.txt";
        
        final Request request = new Request(url, file);
        request.setPriority(Priority.HIGH);
        request.setNetworkType(NetworkType.ALL);
        request.addHeader("clientKey", "SD78DF93_3947&MVNGHE1WONG");
        
        fetch.enqueue(request, updatedRequest -> {
            //Request was successfully enqueued for download.
        }, error -> {
            //An error occurred enqueuing the request.
        });

    }
}

Tracking a download's progress and status is very easy with Fetch. Simply add a FetchListener to your Fetch instance, and the listener will be notified whenever a download's status or progress changes.

FetchListener fetchListener = new FetchListener() {
    @Override
    public void onQueued(@NotNull Download download, boolean waitingOnNetwork) {
        if (request.getId() == download.getId()) {
            showDownloadInList(download);
        }
    }

    @Override
    public void onCompleted(@NotNull Download download) {

    }

    @Override
    public void onError(@NotNull Download download) {
        Error error = download.getError();
    }

    @Override
    public void onProgress(@NotNull Download download, long etaInMilliSeconds, long downloadedBytesPerSecond) {
        if (request.getId() == download.getId()) {
            updateDownload(download, etaInMilliSeconds);
        }
        int progress = download.getProgress();
    }

    @Override
    public void onPaused(@NotNull Download download) {

    }

    @Override
    public void onResumed(@NotNull Download download) {

    }

    @Override
    public void onCancelled(@NotNull Download download) {

    }

    @Override
    public void onRemoved(@NotNull Download download) {

    }

    @Override
    public void onDeleted(@NotNull Download download) {

    }
};

fetch.addListener(fetchListener);

//Remove listener when done.
fetch.removeListener(fetchListener);

Fetch supports pausing and resuming downloads using the request's id. A request's id is a unique identifier that maps a request to a Fetch Download. A download returned by Fetch will have have an id that matches the request id that started the download.

Request request1 = new Request(url, file);
Request request2 = new Request(url2, file2);

fetch.pause(request1.getId());

...

fetch.resume(request2.getId());

You can query Fetch for download information in several ways.

//Query all downloads
fetch.getDownloads(new Func<List<? extends Download>>() {
    @Override
        public void call(List<? extends Download> downloads) {
            //Access all downloads here
        }
});

//Get all downloads with a status
fetch.getDownloadsWithStatus(Status.DOWNLOADING, new Func<List<? extends Download>>() {
    @Override
        public void call(List<? extends Download> downloads) {
            //Access downloads that are downloading
        }
});

// You can also access grouped downloads
int groupId = 52687447745;
fetch.getDownloadsInGroup(groupId, new Func<List<? extends Download>>() {
    @Override
      public void call(List<? extends Download> downloads) {
              //Access grouped downloads
      }
});

When you are done with an instance of Fetch, simply release it.

//do work

fetch.close();

//do more work

Downloaders

By default Fetch uses the HttpUrlConnection client via the HttpUrlConnectionDownloader to download requests. Add the following Gradle dependency to your application's build.gradle to use the OkHttp Downloader instead. You can create your custom downloaders if necessary. See the Java docs for details.

implementation "com.tonyodev.fetch2okhttp:fetch2okhttp:3.0.12"

Androidx use:

implementation "androidx.tonyodev.fetch2okhttp:xfetch2okhttp:3.1.6"

Set the OkHttp Downloader for Fetch to use.

OkHttpClient okHttpClient = new OkHttpClient.Builder().build();

FetchConfiguration fetchConfiguration = new FetchConfiguration.Builder(this)
    .setDownloadConcurrentLimit(10)
    .setHttpDownloader(new OkHttpDownloader(okHttpClient))
    .build();

Fetch fetch = Fetch.Impl.getInstance(fetchConfiguration);

RxFetch

If you would like to take advantage of RxJava2 features when using Fetch, add the following gradle dependency to your application's build.gradle file.

implementation "com.tonyodev.fetch2rx:fetch2rx:3.0.12"

Androidx use:

implementation "androidx.tonyodev.fetch2rx:xfetch2rx:3.1.6"

RxFetch makes it super easy to enqueue download requests and query downloads using rxJava2 functional methods.

FetchConfiguration fetchConfiguration = new FetchConfiguration.Builder(this).build();
Rxfetch rxFetch = RxFetch.Impl.getInstance(fetchConfiguration);

rxFetch.getDownloads()
        .asFlowable()
        .subscribe(new Consumer<List<Download>>() {
            @Override
            public void accept(List<Download> downloads) throws Exception {
                //Access results
            }
        }, new Consumer<Throwable>() {
            @Override
            public void accept(Throwable throwable) throws Exception {
                //An error occurred
                final Error error = FetchErrorUtils.getErrorFromThrowable(throwable);
            }
        });

FetchFileServer

Introducing the FetchFileServer. The FetchFileServer is a lightweight TCP File Server that acts like an HTTP file server designed specifically to share files between Android devices. You can host file resources with the FetchFileServer on one device and have to Fetch download Files from the server on another device. See the sample app for more information. Wiki on FetchFileServer will be added in the coming days.

Start using FetchFileServer by adding the gradle dependency to your application's build.gradle file.

implementation "com.tonyodev.fetch2fileserver:fetch2fileserver:3.0.12"

Androidx use:

implementation "androidx.tonyodev.fetch2fileserver:xfetch2fileserver:3.1.6"

Start a FetchFileServer instance and add resource files that it can serve to connected clients.

public class TestActivity extends AppCompatActivity {

    FetchFileServer fetchFileServer;
    
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        fetchFileServer = new FetchFileServer.Builder(this)
                .build();
        
        fetchFileServer.start(); //listen for client connections

        File file = new File("/downloads/testfile.txt");
        FileResource fileResource = new FileResource();
        fileResource.setFile(file.getAbsolutePath());
        fileResource.setLength(file.length());
        fileResource.setName("testfile.txt");
        fileResource.setId(UUID.randomUUID().hashCode());
        
        fetchFileServer.addFileResource(fileResource);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        fetchFileServer.shutDown(false);
    }
}

Downloading a file from a FetchFileServer using the Fetch is easy.

public class TestActivity extends AppCompatActivity {

    Fetch fetch;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        FetchConfiguration fetchConfiguration = new FetchConfiguration.Builder(this)
                .setFileServerDownloader(new FetchFileServerDownloader()) //have to set the file server downloader
                .build();
        fetch = Fetch.Impl.getInstance(fetchConfiguration);
        fetch.addListener(fetchListener);

        String file = "/downloads/sample.txt";
        String url = new FetchFileServerUrlBuilder()
                .setHostInetAddress("127.0.0.1", 6886) //file server ip and port
                .setFileResourceIdentifier("testfile.txt") //file resource name or id
                .create();
        Request request = new Request(url, file);
        fetch.enqueue(request, request1 -> {
            //Request enqueued for download
        }, error -> {
            //Error while enqueuing download
        });
    }

    @Override
    protected void onResume() {
        super.onResume();
        fetch.addListener(fetchListener);
    }

    @Override
    protected void onPause() {
        super.onPause();
        fetch.removeListener(fetchListener);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        fetch.close();
    }

    private FetchListener fetchListener = new AbstractFetchListener() {
        @Override
        public void onProgress(@NotNull Download download, long etaInMilliSeconds, long downloadedBytesPerSecond) {
            super.onProgress(download, etaInMilliSeconds, downloadedBytesPerSecond);
            Log.d("TestActivity", "Progress: " + download.getProgress());
        }

        @Override
        public void onError(@NotNull Download download) {
            super.onError(download);
            Log.d("TestActivity", "Error: " + download.getError().toString());
        }

        @Override
        public void onCompleted(@NotNull Download download) {
            super.onCompleted(download);
            Log.d("TestActivity", "Completed ");
        }
    };
}

Fetch1 Migration

Migrate downloads from Fetch1 to Fetch2 using the migration assistant. Add the following gradle dependency to your application's build.gradle file.

implementation "com.tonyodev.fetchmigrator:fetchmigrator:3.0.12"

Androidx use:

implementation "androidx.tonyodev.fetchmigrator:xfetchmigrator:3.1.6"

Then run the Migrator.

        if (!didMigrationRun()) {
            //Migration has to run on a background thread
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        final List<DownloadTransferPair> transferredDownloads = FetchMigrator.migrateFromV1toV2(getApplicationContext(), APP_FETCH_NAMESPACE);
                        //TODO: update external references of ids
                        for (DownloadTransferPair transferredDownload : transferredDownloads) {
                            Log.d("newDownload", transferredDownload.getNewDownload().toString());
                            Log.d("oldId in Fetch v1", transferredDownload.getOldID() + "");
                        }
                        FetchMigrator.deleteFetchV1Database(getApplicationContext());
                        setMigrationDidRun(true);
                        //Setup and Run Fetch2 after the migration
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
            }).start();
        } else {
            //Setup and Run Fetch2  normally
        }

Contribute

Fetch can only get better if you make code contributions. Found a bug? Report it. Have a feature idea you'd love to see in Fetch? Contribute to the project!

License

Copyright (C) 2017 Tonyo Francis.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Comments
  • progress return back?

    progress return back?

    I try to listen file progress ,then I called mRxFetch.addListener(this); but when I call mRxFetch.pause(downloadId); for example : the callback called onProgress 30 pause !!! onProgress 60 onPaused 40

    onResume 40

    why onProgress 60 > onPause 40 , should onProgress called after pause called ? should the progress return back ? @dougkeen @jacobtabak @tonyofrancis

    bug help wanted 
    opened by kaiv587hh 26
  • onComplete Prematurely ... Immediately called

    onComplete Prematurely ... Immediately called

    Fetch in itself is not working for me, unfortunately. Immediately after enqueueing, onComplete is immediately called. The destinated file does not exist at all, yet download.getDownloaded() returns a value far more than zero. Creating the file before enqueueing does not help as well.

    Note: The destination is in a cache dir. Fetch is static in an Application class and a service does all the enqueueing.

    bug help wanted 
    opened by iBlueDust 23
  • Is there any way to accelerate the downloads?

    Is there any way to accelerate the downloads?

    I was wondering if theres any way to speed up the download, cause I've been using it on my app, but the speed hardly goes past 300kb/s and I have 5mb/s link. Also its not me, users have reported the same thing. But when they use apps such as ADM they download it at maximum speed.

    Just wondering how to force the download to use maximum speeds.(if there is such thing)

    enhancement 
    opened by RobbieArmz 21
  • Failed to download chunked type file!

    Failed to download chunked type file!

    The downloader seems like NOT supporting Transfer-Encoding: chunked. Downloaded some unrelated html instead of mp3 file.

    Link: https://hindugodsongs.in/

    final FetchConfiguration fetchConfiguration = new FetchConfiguration.Builder(this)
       .setDownloadConcurrentLimit(3)
       .enableAutoStart(false)
       .setProgressReportingInterval(1100)
       .setHttpDownloader(new HttpUrlConnectionDownloader(Downloader.FileDownloaderType.SEQUENTIAL)) 
       .build();
    Fetch.Impl.setDefaultInstanceConfiguration(fetchConfiguration);
    

    Logcat: D/LibGlobalFetchLib: Enqueued download DownloadInfo(id=-1786947277, namespace='LibGlobalFetchLib', url='https://hindugodsongs.in/get/download/shani-gayatri-mantra-[hindugodsongs.in].mp3', file='content://com.android.providers.downloads.documents/document/73', group=0, priority=HIGH, headers={Cookie=__cfduid=d22766a6f223a771943be99db82f7db1d1543158628, User-Agent=Mozilla/5.0 (Linux; Android 8.1.0; Redmi 2 Build/OPM7.181005.003; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/61.0.3163.98 Mobile Safari/537.36}, downloaded=0, total=-1, status=QUEUED, error=NONE, networkType=ALL, created=1543163829063, tag=null, enqueueAction=UPDATE_ACCORDINGLY, identifier=0, downloadOnEnqueue=true, extras={"KEY_DOWNLOAD_SUPPORTS_RESUME":"false","KEY_DOWNLOAD_FILE_NAME":"shani-gayatri-mantra-[hindugodsongs.in].mp3 (1)","KEY_DOWNLOAD_USER_AGENT":"Mozilla/5.0 (Linux; Android 8.1.0; Redmi 2 Build/OPM7.181005.003; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/61.0.3163.98 Mobile Safari/537.36","KEY_DOWNLOAD_SAVE_PATH":"content://com.android.providers.downloads.documents/document/73"}) D/LibGlobalFetchLib: PriorityIterator backoffTime reset to 500 milliseconds D/LibGlobalFetchLib: PriorityIterator started D/LibGlobalFetchLib: PriorityIterator backoffTime reset to 500 milliseconds D/LibGlobalFetchLib: Added DownloadInfo(id=-1786947277, namespace='LibGlobalFetchLib', url='https://hindugodsongs.in/get/download/shani-gayatri-mantra-[hindugodsongs.in].mp3', file='content://com.android.providers.downloads.documents/document/73', group=0, priority=HIGH, headers={Cookie=__cfduid=d22766a6f223a771943be99db82f7db1d1543158628, User-Agent=Mozilla/5.0 (Linux; Android 8.1.0; Redmi 2 Build/OPM7.181005.003; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/61.0.3163.98 Mobile Safari/537.36}, downloaded=0, total=-1, status=QUEUED, error=NONE, networkType=ALL, created=1543163829063, tag=null, enqueueAction=UPDATE_ACCORDINGLY, identifier=0, downloadOnEnqueue=true, extras={"KEY_DOWNLOAD_SUPPORTS_RESUME":"false","KEY_DOWNLOAD_FILE_NAME":"shani-gayatri-mantra-[hindugodsongs.in].mp3 (1)","KEY_DOWNLOAD_USER_AGENT":"Mozilla/5.0 (Linux; Android 8.1.0; Redmi 2 Build/OPM7.181005.003; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/61.0.3163.98 Mobile Safari/537.36","KEY_DOWNLOAD_SAVE_PATH":"content://com.android.providers.downloads.documents/document/73"}) D/LibGlobalFetchLib: Queued DownloadInfo(id=-1786947277, namespace='LibGlobalFetchLib', url='https://hindugodsongs.in/get/download/shani-gayatri-mantra-[hindugodsongs.in].mp3', file='content://com.android.providers.downloads.documents/document/73', group=0, priority=HIGH, headers={Cookie=__cfduid=d22766a6f223a771943be99db82f7db1d1543158628, User-Agent=Mozilla/5.0 (Linux; Android 8.1.0; Redmi 2 Build/OPM7.181005.003; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/61.0.3163.98 Mobile Safari/537.36}, downloaded=0, total=-1, status=QUEUED, error=NONE, networkType=ALL, created=1543163829063, tag=null, enqueueAction=UPDATE_ACCORDINGLY, identifier=0, downloadOnEnqueue=true, extras={"KEY_DOWNLOAD_SUPPORTS_RESUME":"false","KEY_DOWNLOAD_FILE_NAME":"shani-gayatri-mantra-[hindugodsongs.in].mp3 (1)","KEY_DOWNLOAD_USER_AGENT":"Mozilla/5.0 (Linux; Android 8.1.0; Redmi 2 Build/OPM7.181005.003; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/61.0.3163.98 Mobile Safari/537.36","KEY_DOWNLOAD_SAVE_PATH":"content://com.android.providers.downloads.documents/document/73"}) for download D/LibGlobalFetchLib: DownloadManager starting download DownloadInfo(id=-1786947277, namespace='LibGlobalFetchLib', url='https://hindugodsongs.in/get/download/shani-gayatri-mantra-[hindugodsongs.in].mp3', file='content://com.android.providers.downloads.documents/document/73', group=0, priority=HIGH, headers={Cookie=__cfduid=d22766a6f223a771943be99db82f7db1d1543158628, User-Agent=Mozilla/5.0 (Linux; Android 8.1.0; Redmi 2 Build/OPM7.181005.003; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/61.0.3163.98 Mobile Safari/537.36}, downloaded=0, total=-1, status=QUEUED, error=NONE, networkType=ALL, created=1543163829063, tag=null, enqueueAction=UPDATE_ACCORDINGLY, identifier=0, downloadOnEnqueue=true, extras={"KEY_DOWNLOAD_SUPPORTS_RESUME":"false","KEY_DOWNLOAD_FILE_NAME":"shani-gayatri-mantra-[hindugodsongs.in].mp3 (1)","KEY_DOWNLOAD_USER_AGENT":"Mozilla/5.0 (Linux; Android 8.1.0; Redmi 2 Build/OPM7.181005.003; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/61.0.3163.98 Mobile Safari/537.36","KEY_DOWNLOAD_SAVE_PATH":"content://com.android.providers.downloads.documents/document/73"}) D/LibGlobalFetchLib: FileDownloader starting Download DownloadInfo(id=-1786947277, namespace='LibGlobalFetchLib', url='https://hindugodsongs.in/get/download/shani-gayatri-mantra-[hindugodsongs.in].mp3', file='content://com.android.providers.downloads.documents/document/73', group=0, priority=HIGH, headers={Cookie=__cfduid=d22766a6f223a771943be99db82f7db1d1543158628, User-Agent=Mozilla/5.0 (Linux; Android 8.1.0; Redmi 2 Build/OPM7.181005.003; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/61.0.3163.98 Mobile Safari/537.36}, downloaded=0, total=-1, status=QUEUED, error=NONE, networkType=ALL, created=1543163829063, tag=null, enqueueAction=UPDATE_ACCORDINGLY, identifier=0, downloadOnEnqueue=true, extras={"KEY_DOWNLOAD_SUPPORTS_RESUME":"false","KEY_DOWNLOAD_FILE_NAME":"shani-gayatri-mantra-[hindugodsongs.in].mp3 (1)","KEY_DOWNLOAD_USER_AGENT":"Mozilla/5.0 (Linux; Android 8.1.0; Redmi 2 Build/OPM7.181005.003; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/61.0.3163.98 Mobile Safari/537.36","KEY_DOWNLOAD_SAVE_PATH":"content://com.android.providers.downloads.documents/document/73"}) W/OkHttpClient: A connection to https://hindugodsongs.in/ was leaked. Did you forget to close a response body? D/LibGlobalFetchLib: PriorityIterator backoffTime reset to 500 milliseconds

    For your reference: https://stackoverflow.com/questions/5737945/java-how-to-download-chunked-content-correctly

    enhancement help wanted 
    opened by jpvs0101 20
  • Add support for groupProgress

    Add support for groupProgress

    Hi @tonyofrancis!

    Maybe I'm missing something here but.. I can see that you have a FetchGroupInfo#groupDownloadProgress(), but I can't see that it is ever used. And I can't find how to access it?

    I would expect there to be a fetch.groupProgress(groupId: Int). Is this value/functionality possible to access somewhere?

    Best regards, Daniell Algar

    bug enhancement help wanted 
    opened by daniellAlgar 18
  • Different downloaded file size compare to other download method

    Different downloaded file size compare to other download method

    Hi, thanks for this awesome library! I got one question: when downloading some files from the link below, the files are always smaller than downloaded via other method, like browsers or Android default DownloadManager. Please help.

    The download link is a little complicated because it has some protection, so sorry for that.

    1. The original link is: https://xxx

    2. Download the file, with a specified user-agent (it'll be used later). The link should be in the following format: https://xxx

    3. Open the file, you'll get a set of segment file links. Except the first key file, all links are formatted as follows: xxx. You need to concatenate this part after the base url: https://xxx

    4. Now you'll get a link formatted as follows: https://xxx. Downloading this file with the specified user-agent.

    This is the file that cause the problem. For example, the size of it should be xxx bytes. But via Fetch 2, the size is always smaller.

    help wanted 
    opened by JumpLizard 18
  • Downloads Failing / Better error description

    Downloads Failing / Better error description

    Two issues, the first is that when something fails, most of the time we get a generic request_not_successful message, which is not very useful when when trying to understand exactly why it failed.

    As for the second issue,

    In my app (iOS / android), the urls that are sent to the downloader may or may not be restricted (may be redirected to a paywall page if restricted).

    On iOS using NSURLSessionDownloadTask , if the url is indeed a paywall, instead of it failing, the html content is returned which I can then use to check for restricted signs and act accordingly.

    On android using this library, it works similarly to a certain degree. On certain urls it returns the HTML content, on others it just fails with a request_not_successful message.

    An example would be :

    Works on both android / iOS (Returns HTML content): http://jandonline.org/article/S2212267214006005/pdf

    Works on iOS, fails on android (request_not_successful): https://www.magonlinelibrary.com/doi/pdf/10.12968/bjon.2013.22.7.364?t=

    Library version: 2.3.4 Fetch configuration:

    CookieManager cookieManager = new CookieManager();
            cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
            OkHttpClient okHttpClient = new OkHttpClient
                    .Builder()
                    .followRedirects(true)
                    .followSslRedirects(true)
                    .cookieJar(new JavaNetCookieJar(cookieManager)).build();
    
            FetchConfiguration fetchConfiguration = new FetchConfiguration.Builder(context)
                    .setDownloadConcurrentLimit(4)
                    .setProgressReportingInterval(100)
                    .setNamespace("PPDownloader")
                    .setHttpDownloader(new OkHttpDownloader(okHttpClient))
                    .build();
    
    enhancement 
    opened by cdn34 18
  • fetch.close(); leads to ANR Application Not Responding

    fetch.close(); leads to ANR Application Not Responding

    I have an activity where I build an instance of fetch in onCreate() then use that instance through out the Activity.

    Finally onDestroy() I call fetch.close(); This works fine the Activity destroyed and fetch instance is closed. But my phone freezes to about 9 seconds and usually with an ANR Application Not Responding after that then it works fine. But during the freeze NO button NOR input responds you know.

    I struggled with it then I comment off //fetch.close(); and when I left onDestroy(); the activity everything works great and No any ANR's. I also could not leave the code that way since when a user reenter the activity onCreate(); fails with an exception

    FetchException Namespace already exist for this instance of Fetch, did you forget to close...

    So I am stuck with this... What can solve this?

    bug 
    opened by Xenolion 17
  • EnqueueAction.REPLACE_EXISTING not working

    EnqueueAction.REPLACE_EXISTING not working

    I'm trying to redownload an existing file but getting "UNKNOWN" error from fetch.enqueue. I'm creating a new request with the same url and file path. If I delete the file first using fetch.delete before calling enqueue it's working fine.

     Request request = new Request(url, getFilePath(url, fileName));
            request.setGroupId(grpId);
            request.setEnqueueAction(EnqueueAction.REPLACE_EXISTING); 
            return request;
    
    bug 
    opened by tuhin10 16
  • fetch.close(); should be maintained in library, app crashing and have to write complex logic for maintaining it

    fetch.close(); should be maintained in library, app crashing and have to write complex logic for maintaining it

    Your Sample App's Logic should be inside Library.

    https://github.com/tonyofrancis/Fetch/blob/v2/sampleApp/src/main/java/com/tonyodev/fetchapp/App.java

    enhancement 
    opened by Mayur-007 15
  • Encoding Problem

    Encoding Problem

    I'm currently using your library at my project for downloading a large number of small files. These files are parts of a web app that needs to be downloaded locally and is displayed via a webview. Until RC5 everything was fine, I tried using RC8 and the downloaded files has a strange encoding thus the browser was not able to display them. BTW great work, keep it up.

    help wanted 
    opened by Sergios21 15
  • removeListener has bugs

    removeListener has bugs

    override fun removeListener(listener: FetchListener): Fetch {
        synchronized(lock) {
            throwExceptionIfClosed()
            handlerWrapper.post {
                fetchHandler.removeListener(listener)
            }
            return this
        }
    }
    

    because it is asynchronous remove listener when the view or pager is destroy it still callback the listener if this moment has ui operation will crash

    Process: com.julun.jiuliao, PID: 32210
    java.lang.IllegalStateException: okText must not be null
        at com.julun.jiuliao.core.ui.dialog.GuideDownloadDialog$listener$2$1.onCompleted(GuideDownloadDialog.kt:94)
        at com.tonyodev.fetch2.fetch.ListenerCoordinator$mainListener$1$onCompleted$$inlined$synchronized$lambda$2.run(ListenerCoordinator.kt:246)
        at android.os.Handler.handleCallback(Handler.java:883)
        at android.os.Handler.dispatchMessage(Handler.java:100)
        at android.os.Looper.loop(Looper.java:230)
        at android.app.ActivityThread.main(ActivityThread.java:8051)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:526)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1034)
    
    opened by zhangzhen123 0
  • android.database.sqlite.SQLiteException

    android.database.sqlite.SQLiteException

    Hello recently I saw a log in Firebase crashlytics that says:

    android.database.sqlite.SQLiteException: no such table: requests (Sqlite code 1 SQLITE_ERROR): , while compiling: SELECT * FROM requests, (OS error - 2:No such file or directory) at android.database.sqlite.SQLiteConnection.nativePrepareStatement(SQLiteConnection.java) at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:948) at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:559) at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:603) at android.database.sqlite.SQLiteProgram.(SQLiteProgram.java:63) at android.database.sqlite.SQLiteQuery.(SQLiteQuery.java:37) at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:46) at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1493) at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1463) at androidx.sqlite.db.framework.FrameworkSQLiteDatabase.query(FrameworkSQLiteDatabase.java:161) at androidx.room.RoomDatabase.query(RoomDatabase.java:446) at androidx.room.util.DBUtil.query(DBUtil.java:83) at com.tonyodev.fetch2.database.DownloadDao_Impl.get(DownloadDao_Impl.java:299) at com.tonyodev.fetch2.database.FetchDatabaseManagerImpl.get(FetchDatabaseManagerImpl.java:120) at com.tonyodev.fetch2.database.FetchDatabaseManagerImpl$sanitizeOnFirstEntry$1.invoke(FetchDatabaseManagerImpl.java:239) at com.tonyodev.fetch2.database.FetchDatabaseManagerImpl$sanitizeOnFirstEntry$1.invoke(FetchDatabaseManagerImpl.java:20) at com.tonyodev.fetch2.fetch.LiveSettings.execute(LiveSettings.java:12) at com.tonyodev.fetch2.database.FetchDatabaseManagerImpl.sanitizeOnFirstEntry(FetchDatabaseManagerImpl.java:237) at com.tonyodev.fetch2.database.FetchDatabaseManagerWrapper.sanitizeOnFirstEntry(FetchDatabaseManagerWrapper.java:153) at com.tonyodev.fetch2.fetch.FetchHandlerImpl.init(FetchHandlerImpl.java:46) at com.tonyodev.fetch2.fetch.FetchImpl$1.invoke(FetchImpl.java:59) at com.tonyodev.fetch2.fetch.FetchImpl$1.invoke(FetchImpl.java:16) at com.tonyodev.fetch2core.HandlerWrapper$sam$i$java_lang_Runnable$0.run(HandlerWrapper.java:2) at android.os.Handler.handleCallback(Handler.java:907) at android.os.Handler.dispatchMessage(Handler.java:105) at android.os.Looper.loop(Looper.java:216) at android.os.HandlerThread.run(HandlerThread.java:65)

    I'm using version 3.1.5

    opened by arashfat 0
  • Parallel Download type causes to increase the network usage about five times more than what it is

    Parallel Download type causes to increase the network usage about five times more than what it is

    recently users reported to us that the Application is consuming their data traffic excessively, after investigating and measuring it multiple times we found out this is causing due to this config:

     FetchConfiguration.Builder(context)
                .setDownloadConcurrentLimit(DOWNLOAD_CONCURRENT_LIMIT)
                .setProgressReportingInterval(PROGRESS_REPORTING_INTERVAL)
                .enableRetryOnNetworkGain(true)
                .setAutoRetryMaxAttempts(AUTO_RETRY_MAX_ATTEMPT)
                .enableAutoStart(true).setHttpDownloader(
                    OkHttpDownloader(
                        okHttpClient,
                        Downloader.FileDownloaderType.PARALLEL
                    )
                ).build()
    

    Finally, I figured out that removing the Downloader.FileDownloaderType.PARALLEL from the okHttp config resolves the issue.

    consuming the network data about 5 times more than the actual size is an important issue and I hope to see the fix in the next versions.

    Cheers!

    opened by imansdn 0
  • Download groups separately

    Download groups separately

    I have to implement this situation: I have a list with n rows. Each rows corresponds to a resource with n media to downloads. I want to download more rows (each media) at same time and update progress for each group.

    opened by andr3aLucch3si85 0
  • Caused by: org.gradle.api.resources.ResourceException: Could not get resource 'https://jitpack.io/com/tonyodev/fetch2/fetch2/3.0.12/fetch2-3.0.12.pom'.

    Caused by: org.gradle.api.resources.ResourceException: Could not get resource 'https://jitpack.io/com/tonyodev/fetch2/fetch2/3.0.12/fetch2-3.0.12.pom'.

    Caused by: org.gradle.api.resources.ResourceException: Could not get resource 'https://jitpack.io/com/tonyodev/fetch2/fetch2/3.0.12/fetch2-3.0.12.pom'.

    opened by teraiyamayurcontact 2
Releases(3.0.12-release)
  • 3.0.12-release(Dec 23, 2020)

    Version 3.0.12/ Androidx version 3.1.6

    1. Download TotalBytes fixes. Thanks to @badrazizi
    2. OnCompleted not called in some instances.
    3. Fixed " A resource failed to call close" errors. Thanks to @Braxeo
    4. Fixed Pen Test issues: Thanks to @StuStirling
    5. Added new batch enqueue method. Thanks to @thib-rdr
    6. Fixed rapid pause and resume issues. Thanks to @jpvs0101
    7. Breaking change. Reverted OkHttp client to 3.12.12 to support Android versions older than 21. Thanks to @badrazizi
    8. Fixed issues with sample app

    Big thanks to everyone who contributed and open issues. Happy Holidays. Stay Safe!

    Source code(tar.gz)
    Source code(zip)
  • 3.1.5/3.0.11(Aug 19, 2020)

    Version 3.0.11/ Androidx version 3.1.5 2. Notification sound fixes. 3. RxJava fixes. 4. Content Length fixes 5. Added NetworkType.UNMETERED 6. Lots of bug fixes.

    Thanks to everyone who contributed!

    Source code(tar.gz)
    Source code(zip)
  • 3.0.10(Jul 7, 2019)

    Version 3.0.10/ Androidx version 3.1.4

    1. Improvements/Bug fixes to getting a download's content-length
    2. FetchDatabaseManager interface improvements. It is now easier to create custom fetch databases. Note: New methods were added and old methods may have been updated for the FetchDatabaseManager interface.
    3. FetchNotificationManger interface improvements. It is now easier to control notifications. Note: New methods were added and old methods may have been updated for the FetchNotificationManger interface. -> The DefaultFetchNotificationManager class has also been updated and is now abstract. See java docs for details. Also seen sample app DownloadListActivity on how to use the DefaultFetchNotificationManager class.
    4. Fetch updateRequest method will now call fetch listener onDeleted(download) method when a request is being updated
    5. Added new Fetch method getAllGroupIds(callback) that returns all group id's being managed by Fetch.
    6. Added new Fetch method getDownloadsByTag(tag, callback) that returns all download's being managed by Fetch with the specified tag.

    Special thanks to @alvince and @DHosseiny for providing fixes for this release.

    Source code(tar.gz)
    Source code(zip)
  • 3.0.9(Jun 24, 2019)

  • 3.1.2(Jun 23, 2019)

    Version 3.0.8/ Android x version 3.1.2

    1. Fixed group error reporting bugs with FetchGroup.getProgress() method.
    2. Fixed network on main thread error.
    3. Improved network connection checks.
    4. Improvements and fixes to the StorageResolver when working with the Storage Access Framework.
    5. Files are now pre allocated on local storage on request enqueue. This prevents waste of data. See FetchConfiguration method fun preAllocateFileOnCreation(preAllocateFile: Boolean) to enable or disable this feature. On by default.
    6. Added new field segment to Downloader.Request. See java docs for details.
    7. Added new Fetch method fun getContentLengthForRequests(requests:List<Request>, fromServer: Boolean, func: Func<List<Pair<Request,Long>>>, func2: Func<List<Pair<Request, Error>>>): Fetch
    8. Performance improvements to the Parallel downloader mode.
    Source code(tar.gz)
    Source code(zip)
  • 3.0.7/3.1.1(May 21, 2019)

    Version 3.0.7/ Android x version 3.1.1 Added new pauseAll method on Fetch. Added new resumeAll method on Fetch. Better logging. Library code cleanup. Special thanks to Alex Starchenko for submitting the fixes and improvements

    Source code(tar.gz)
    Source code(zip)
  • 3.1.0(Apr 26, 2019)

  • 3.0.6(Apr 26, 2019)

  • 3.0.5(Apr 26, 2019)

    Version 3.0.5 This release only adds a new Feature that allows Fetch to auto retry failed downloads for any reason. Set the number of times Fetch will auto retry a download when it fails. This feature if off by default.

    1. New fields added on Download: autoRetryMaxAttempts and autoRetryAttempts. See Java docs.
    2. New field added on RequestInfo: autoRetryMaxAttempts. See Java docs.
    3. New method added on Fetch: fun resetAutoRetryAttempts(downloadId: Int, retryDownload: Boolean = true, func: Func2<Download?>? = null, func2: Func? = null): Fetch
    4. New method added on RXFetch: fun resetAutoRetryAttempts(downloadId: Int, retryDownload: Boolean = true): Convertible<Download?>
    5. New method added on FetchConfiguration: fun setAutoRetryMaxAttempts(autoRetryMaxAttempts: Int): Builder. See Java Docs
            final FetchConfiguration fetchConfiguration = new FetchConfiguration.Builder(this)
                    .enableRetryOnNetworkGain(true)
                    .setDownloadConcurrentLimit(2)
                    .setAutoRetryMaxAttempts(10) // set global auto retry max attempts for all downloads.
                    .build();
            final Fetch fetch = Fetch.Impl.getInstance(fetchConfiguration);
    
            //OR
    
            final String url = "dummy url";
            final String file = "dummy file";
            final Request request = new Request(url, file);
            request.setAutoRetryMaxAttempts(5); // set auto retry on individual downloads.
    
            fetch.getDownload(request.getId(), download -> {
                if (download != null) {
                    download.getAutoRetryAttempts(); //get the number of auto retry attempts.
                    download.getAutoRetryMaxAttempts(); //get the number of max attempts.
                }
            });
    
            //reset the auto retry attempts for a download
            fetch.resetAutoRetryAttempts(request.getId(), true, null, null);
    
    Source code(tar.gz)
    Source code(zip)
  • 3.0.4(Apr 22, 2019)

    Version 3.0.4

    1. updated documentation
    2. remove has activeDownloads(): Boolean method. Use fun hasActiveDownloads(includeAddedDownloads: Boolean, func: Func): Fetch or fun addActiveDownloadsObserver(includeAddedDownloads: Boolean = false, fetchObserver: FetchObserver): Fetch instead.
    3. Added new methods on Fetch addActiveDownloadsObserver(includeAddedDownloads: Boolean = false, fetchObserver: FetchObserver): Fetch and removeActiveDownloadsObserver(fetchObserver: FetchObserver): Fetch
    4. Added new method on FetchConfiguration fun setHasActiveDownloadsCheckInterval(intervalInMillis: Long): Builder
    5. Added new REPORTING option on Reason enum
    6. Added new method on FetchConfiguration fun createDownloadFileOnEnqueue(create: Boolean): Builder
    7. Fix for starting download immediately whiles enqueuing
    Source code(tar.gz)
    Source code(zip)
  • 3.0.3(Mar 30, 2019)

    Version 3.0.3

    • Bug fixes for hasActiveDownloads method.
    • Download url redirection fixes and improvements
    • Added internet check method to FetchConfiguration called setInternetAccessUrlCheck(url: String?): Builder See documentation on usage.
    • Added new fields redirected and redirectedUrl on Downloader.ServerRequest class.
    Source code(tar.gz)
    Source code(zip)
  • 3.0.2(Mar 16, 2019)

    Version 3.0.2

    • Added Wrapper class around FetchDatabase to provide safer access
    • Added Priority Sort to change the way Fetch queues downloads based on time created.

    Note: Fetch 3.1.0 Will be the next big release. The library will be migrating to AndroidX packages. Point releases will be created for the none AndroidX version of the library.

    Source code(tar.gz)
    Source code(zip)
  • 3.0.1(Mar 3, 2019)

  • 3.0.0(Mar 3, 2019)

    Version 3.0.0 Version 3 comes with a lot of enhancements and fixes

    Fetch:

    • FetchGroupListener. FetchGroupListener extends from FetchListener and allows you to listener for updates on a group. The methods on FetchGroupListener will return a FetchGroup object that contains all the downloads in a group and will inform you which download triggered a change on the group. Also see AbstractFetchGroupListener.

    • Added new method to rename a completed download's file. see Fetch.renameCompletedDownloadFile method.

      Observers:

    • Introducing FetchObserver. Fetch now allows you to subscribe from updates for a single Download or a Group of Downloads. Using the FetchObserver and FetchGroupObserver interface respectively. See Fetch.attachFetchObserversForDownload(id, observers...) documentation for more information. Also check the sample app for usage.

    • Introducing FetchGroup. FetchGroup is an object that contains all information about a group Fetch manages. The group is automatically updated any time a download from the group updates. You can subscribe to FetchGroup's using the FetchGroupObserver. FetchGroupObservers attached to a FetchGroup will be notified when downloads on a group changes. You will be notified of the Reason for the change as well. See Fetch.getFetchGroup(id, callback) documentation for more information.

      Database:

    • Fetch now allows you to provide your own database manager to manage downloads. See the FetchDatabaseManager documentation and FetchConfiguration.Builder class to get started. Note: Fetch depends on your FetchDatabaseManager methods to be synchronized to work correctly.

      Download:

    • Added new fields on the Download objects. Fields: etaInMilliSeconds, downloadedBytesPerSecond. See documentation.

      Fixes & Small Improvements:

    • You can now set the Handler Fetch will use to perform all operations on. See FetchConfiguration.Builder.setHandler method.

    • Fixed a bug that prevented notification buttons (pause, cancel, resume, etc) from firing the intent.

    Source code(tar.gz)
    Source code(zip)
  • 2.3.6(Jan 14, 2019)

  • 2.3.5(Jan 10, 2019)

    Version 2.3.5

    • Fetch methods removeAllInGroupWithStatus, deleteAllInGroupWithStatus, getDownloadsInGroupWithStatus have been updated to allow more than one Status to be queried or actioned upon. See Java doc for details . Special thanks to Marcin Adamczewski for submitting PR.
    • Fetch logging is now disabled by default and can be enabled with the FetchConfiguration method. .enableLogging(true)
    • The Error enum object now has a new field attach httpResponse. This response object contains the HttpCode and other http related information. This field is only provided when an error occurs and it is related to the Http response.
    • Fixed EnqueueAction.UPDATE_ACCORDINGLY that caused the onComplete listener method to be called if the newly enqueued request was previously downloaded and completed but the file on the storage system was delete.
    Source code(tar.gz)
    Source code(zip)
  • 2.3.4(Dec 18, 2018)

    Version 2.3.4

    • Added default cookie manager for the okhttp and httpurlconnection client Downloaders.
    • Fixed an EnqueueAction.INCREMENT_FILE_NAME bug where files were not properly created.
    • Download, Request, DownloadBlock and other data classes now extend Serializable.
    • Okhttp and HttpUrlConnection clients now add a default Referer header to each request if one is not provided. Default Referer is the host of the url passed in the request.
    • Behavior change and Updates for ActiveDownloads method on Fetch. The ActiveDownload method can now only be called on threads other than the Main(UI) Thread. The ActiveDownload method now correctly return true if there are active downloads. Downloads with a queued or Downloading status. Note: Calling this method on a UI thread will throw a FetchException.
    • Added new awaitFinish methods on Fetch. The awaitFinish method blocks the current non UI thread until Fetch has completed all enqueued downloads. The awaitFinishTimeout method takes in a time in milliseconds to release the hold if Fetch has not completed all downloads in the allocated timeframe. Passing 0 to the awaitFinishTimeout method will hold the thread indefinitely(Never releasing). Recommend to use the awaitFinishTimeout method inside Android Workers and release the task when a certain amount of time has passed. See Java docs for details. Note: Calling this method on a UI thread will throw a FetchException.
    Source code(tar.gz)
    Source code(zip)
  • 2.3.3(Dec 4, 2018)

  • 2.3.2(Dec 1, 2018)

    Version 2.3.2

    • Downloader interfaces and classes that extend Downloader now have a new method called onPreClientExecute(client: T, request: Downloader.ServerRequest): R? This method allows you to specify settings on the client before executing the request.
    • Fixed resume bug with Parallel downloader
    Source code(tar.gz)
    Source code(zip)
  • 2.3.1(Nov 17, 2018)

    Version 2.3.1 This is the first stable version of Fetch 2. Enjoy.

    • Fixed an issue where the priority queue backoff would not work correctly.
    • Fixed an issue where request with a file uri would not resume correctly.
    • Fixed an issue where the Fetch database would crash on large group calls.
    • Added new method fun fileExists(file: String): Boolean on StorageResolver.
    • Added new method getServerResponse for Fetch and RxFetch.
    • Fixed an issue where completed download notifications using the DefaultNotificationManager would show the progress bar when a download completed.
    Source code(tar.gz)
    Source code(zip)
  • 2.3.0-RC1(Nov 7, 2018)

    Version 2.3.0-RC1 This version has lots of changes, improvements and bug fixes. Please read carefully.

    New

    1. Fetch now supports notifications via the FetchNotificationManager interface. See DefaultFetchNotificationManager class and sample code on usage.
    2. Fetch now supports saving downloads to URI paths via StorageResolver. See sample code and DefaultStorageResolver class for usage.
    • New constructor added for Request object. Request(url, Uri)
    • New get method added on Request object. request.getFileUri()
    • New get method added on Download interface. download.getFileUri()
    • New set method added on FetchConfiguration.Builder class. builder.setStorageResolver(storageResolver)
    • New set method added on FetchConfiguration.Builder class. builder.setNotificationManager(fetchNotificationManager)
    • New interface added FetchNotificationManager. See java Docs.
    • New class added DefaultFetchNotificationManager. See java Docs.
    • New interface added StorageResolver. See javaDocs.
    • New class added DefaultStorageResolver. See java Docs.

    Bug Fixes

    • Improvements and bug fixes to Parallel and Sequential file downloader.
    • Fixed an issue where the onCompleted method would not be called for downloads with unknown content length.
    • Fixed bug where EnqueueAction.DO_NOT_ENQUEUE_IF_EXISTING would throw an exception when it should not.
    • Improvements to EnqueueAction.Update_ Accordingly
    • Tons of bug fixes and performance improvements.

    Breaking Changes

    • The Fetch and RxFetch List enqueue method now has a new signature. fun enqueue(requests: List, func: Func<List<Pair<Request, Error>>>? = null): Fetch See Java Docs for more information. The new signature allows for the case where a request may fail to enqueue but other request are still enqueued instead of the whole operation being terminated. If the Error is Error.NONE this means that the download was successfully enqueued. Otherwise this means that the enqueue for the request failed.
    • In order to make Fetch more modular and accommodating to different application environments, the following methods were removed from the Downloader interface and are now on the StorageResolver interface. If you are overriding these methods, you must extend the StorageResolver interface or DefaultStorageResolver class and set an instance on the Fetch Configuration builder you are using to create your Fetch instance. Methods Moved: fun getRequestOutputResourceWrapper(request: Downloader.ServerRequest): OutputResourceWrapper fun getDirectoryForFileDownloaderTypeParallel(request: Downloader.ServerRequest): String
    Source code(tar.gz)
    Source code(zip)
  • 2.2.0-RC16(Oct 24, 2018)

  • 2.2.0-RC15(Oct 23, 2018)

    Version 2.2.0-RC15

    • Network state check improvements.
    • Fetch.getHasActiveDownloads() should now report accurately.
    • Added new getListenerSet() method on Fetch. This returns the set of listeners attached to the Fetch instance.
    • Fixed database error not parsing error correctly to Error enum for consumption.
    • Fixed enqueue request bug.
    • Improvements to Sequential downloader. Breaking Changes
    • Improvements for verifying the hash of a completed download.
    • FetchConfiguration method enableMD5Check(enabled: Boolean) has been renamed to enableHashCheck(enabled: Boolean)
    • Downloader interface verifyMD5Hash method has been renamed to verifyContentHash. See Java docs.
    • New method added on Downloader interface called getContentHash. See Java docs.
    • Error value INVALID_MD5_HASH has been renamed to INVALID_CONTENT_HASH

    Special Thanks to @akurni for submitting the Hash check improvements pull request and making Fetch more awesome!

    Source code(tar.gz)
    Source code(zip)
  • 2.2.0-RC14(Sep 30, 2018)

    Version 2.2.0-RC14

    • Added new EnqueueAction (UPDATE_ACCORDINGLY) which is now the default EnqueueAction. (NEW)
    • Bug fixes to Fetch and RxFetch enqueue methods.(BEHAVIOR CHANGE)
    • Bug fixes to Fetch and RXFetch updateRequest methods. (BEHAVIOR CHANGE)
    • Added new boolean param called updatedListeners for Fetch and RxFetch updateRequest methods. (BREAKING CHANGE)
    • Improvements and bug fixes to download processing backoff strategy.
    Source code(tar.gz)
    Source code(zip)
  • 2.2.0-RC13(Sep 20, 2018)

  • 2.2-RC12(Sep 17, 2018)

    Version 2.2.0-RC12

    • Added new method enableFileExistChecks(enabled: Boolean) on FetchConfiguration class
    • Small fixes to ParallelDownloader
    Source code(tar.gz)
    Source code(zip)
  • 2.2.0-RC11(Aug 31, 2018)

    Version 2.2.0-RC11

    • Fixed issue where downloads would get stuck in the queue and fetch would mark all downloads as failed.
    • Behavior change: Fetch no longer mark downloads with a Failed status if the file on the disk storage system is not found. If the file is not found and the download status is Queued or Paused, Fetch will simply start the download from the beginning.
    Source code(tar.gz)
    Source code(zip)
  • 2.2.0-RC10(Aug 24, 2018)

    Version 2.2.0-RC10

    • Added new Fetch field named hasActiveDownloads. This field indicates if the fetch namespace has active(downloading or queued) downloads. Use this field to keep background services using fetch alive. This field is thread safe.
    Source code(tar.gz)
    Source code(zip)
  • 2.2.0-RC9(Aug 23, 2018)

    Version 2.2.0-RC9

    • Fixed issue where different namespace Fetch instances shared the same logger object
    • Breaking Change. Added new boolean param for add completed downloads method. Now: fun addCompletedDownload(completedDownload, boolean, func, func2): Fetch and fun addCompletedDownloads(completedDownloadsList, boolean, func, func2): Fetch
    • Added documentation for Extras and MutableExtras classes.
    Source code(tar.gz)
    Source code(zip)
  • 2.2.0-RC8(Aug 20, 2018)

    Version 2.2.0-RC8

    • Fixed issue where downloads will not start processing after calling autoStart.
    • Fixed issue where the callbacks returned wrong download object.
    • Fixed issue where the download callbacks where not called.
    Source code(tar.gz)
    Source code(zip)
Owner
Tonyo Francis
Android Engineer with a passion for learning new programming languages and mobile development platforms.
Tonyo Francis
A downloader to help in downloading to custom folders

Murerwa Downloader (Still in development) Murerwa downloader is a custom downloader library beside the default Android downloader that helps users dow

Kenneth Murerwa 5 Mar 31, 2022
Youtube Inline Downloader (YTILDL)

Youtube Inline Downloader (YTILDL) This is a userscript that allows you to download youtube videos by simply clicking a button on the YouTube video. T

null 1 Jun 13, 2022
android webview choose file to upload

Android WebView文件上传 本工程为大家演示在H5中如何上传文件,同时也提供了服务端代码,有兴趣的读者可以部署起来,测试文件上传功能。 如果只对客户端部分感兴趣,只需要关注WebView文件选择部分即可 服务端代码下载地址, 客户端可以用如下url来上传文件 http://your ip

yuzhiqiangqiangqiang 57 Sep 20, 2022
Utilizes the Range HTTP header to download a file with multiple connections in parallel, bypassing cheap bandwidth throttling

async-range-downloader Utilizes the Range HTTP header to download a file with multiple connections in parallel, bypassing cheap bandwidth throttling T

Torben 4 Apr 12, 2022
An App to download a file from Internet by clicking on a custom-built button

LoadApp LoadApp is an app to download a file from the Internet by clicking on a custom-built button where: Width of the button gets animated from left

Anas Tariq 2 Aug 29, 2022
:satellite: [Android Library] Simplified async networking in android

Android library that simplifies networking in android via an async http client. Also featured in [Awesome Android Newsletter #Issue 15 ] Built with ❤︎

Nishant Srivastava 36 May 14, 2022
Android network client based on Cronet. This library let you easily use QUIC protocol in your Android projects

Android network client based on Cronet. This library let you easily use QUIC protocol in your Android projects

VK.com 104 Dec 12, 2022
Android Easy Http - Simplest android http request library.

Android Easy Http Library 繁體中文文檔 About Android Easy Http Library Made on OkHttp. Easy to do http request, just make request and listen for the respons

null 13 Sep 30, 2022
dns library for android

Qiniu Happy DNS for Android 安装 直接安装 通过maven 使用方法 DnsManager 可以创建一次,一直使用。 IResolver[] resolvers = new IResolver[3]; resolvers[0] = AndroidDnsSe

Qiniu Cloud 270 Dec 5, 2022
🚀 A Complete Fast Android Networking Library that also supports HTTP/2 🚀

Fast Android Networking Library About Fast Android Networking Library Fast Android Networking Library is a powerful library for doing any type of netw

AMIT SHEKHAR 5.5k Dec 27, 2022
The easiest HTTP networking library for Kotlin/Android

Fuel The easiest HTTP networking library for Kotlin/Android. You are looking at the documentation for 2.x.y.. If you are looking for the documentation

Kittinun Vantasin 4.3k Jan 8, 2023
Asynchronous socket, http(s) (client+server) and websocket library for android. Based on nio, not threads.

AndroidAsync AndroidAsync is a low level network protocol library. If you are looking for an easy to use, higher level, Android aware, http request li

Koushik Dutta 7.3k Jan 2, 2023
Android library listening network connection state and change of the WiFi signal strength with event bus

NetworkEvents Android library listening network connection state and change of the WiFi signal strength with event bus. It works with any implementati

Piotr Wittchen 452 Nov 21, 2022
🚀 A Complete Fast Android Networking Library that also supports HTTP/2 🚀

Fast Android Networking Library About Fast Android Networking Library Fast Android Networking Library is a powerful library for doing any type of netw

AMIT SHEKHAR 5.5k Jan 3, 2023
Flower - Super cool Android library to manage networking and database caching with ease

Flower Super cool Android library to manage networking and database caching with ease. It allows developers to use remote resources on-the-fly OR Comb

Rajesh Hadiya 192 Dec 26, 2022
android lightweight graphql library

android lightweight graphql library

Muh Isfhani Ghiath 30 Nov 12, 2022
Light library to check internet connection in android apps easily.

check-internet-android Light library to check internet connection in android apps easily. It checks real internet connection by connecting to Google's

Raheem 7 Nov 15, 2022
Volley is an HTTP library that makes networking for Android apps easier and, most importantly, faster.

Volley Volley is an HTTP library that makes networking for Android apps easier and, most importantly, faster. For more information about Volley and ho

Google 3.3k Jan 1, 2023