Code Monkey home page Code Monkey logo

prdownloader's Introduction

PRDownloader

PRDownloader - A file downloader library for Android with pause and resume support

Sample Download

Overview of PRDownloader library

  • PRDownloader can be used to download any type of files like image, video, pdf, apk and etc.
  • This file downloader library supports pause and resume while downloading a file.
  • Supports large file download.
  • This downloader library has a simple interface to make download request.
  • We can check if the status of downloading with the given download Id.
  • PRDownloader gives callbacks for everything like onProgress, onCancel, onStart, onError and etc while downloading a file.
  • Supports proper request canceling.
  • Many requests can be made in parallel.
  • All types of customization are possible.

About me

Hi, I am Amit Shekhar, I have mentored many developers, and their efforts landed them high-paying tech jobs, helped many tech companies in solving their unique problems, and created many open-source libraries being used by top companies. I am passionate about sharing knowledge through open-source, blogs, and videos.

You can connect with me on:

Using PRDownloader Library in your Android application

Add this in your build.gradle

implementation 'com.mindorks.android:prdownloader:0.6.0'

Do not forget to add internet permission in manifest if already not present

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

Then initialize it in onCreate() Method of application class :

PRDownloader.initialize(getApplicationContext());

Initializing it with some customization

// Enabling database for resume support even after the application is killed:
PRDownloaderConfig config = PRDownloaderConfig.newBuilder()
                .setDatabaseEnabled(true)
                .build();
PRDownloader.initialize(getApplicationContext(), config);

// Setting timeout globally for the download network requests:
PRDownloaderConfig config = PRDownloaderConfig.newBuilder()
                .setReadTimeout(30_000)
                .setConnectTimeout(30_000)
                .build();
PRDownloader.initialize(getApplicationContext(), config); 

Make a download request

int downloadId = PRDownloader.download(url, dirPath, fileName)
                        .build()
                        .setOnStartOrResumeListener(new OnStartOrResumeListener() {
                            @Override
                            public void onStartOrResume() {
                               
                            }
                        })
                        .setOnPauseListener(new OnPauseListener() {
                            @Override
                            public void onPause() {
                               
                            }
                        })
                        .setOnCancelListener(new OnCancelListener() {
                            @Override
                            public void onCancel() {
                                
                            }
                        })
                        .setOnProgressListener(new OnProgressListener() {
                            @Override
                            public void onProgress(Progress progress) {
                               
                            }
                        })
                        .start(new OnDownloadListener() {
                            @Override
                            public void onDownloadComplete() {
                               
                            }

                            @Override
                            public void onError(Error error) {
                               
                            }
                        });            

Pause a download request

PRDownloader.pause(downloadId);

Resume a download request

PRDownloader.resume(downloadId);

Cancel a download request

// Cancel with the download id
PRDownloader.cancel(downloadId);
// The tag can be set to any request and then can be used to cancel the request
PRDownloader.cancel(TAG);
// Cancel all the requests
PRDownloader.cancelAll();

Status of a download request

Status status = PRDownloader.getStatus(downloadId);

Clean up resumed files if database enabled

// Method to clean up temporary resumed files which is older than the given day
PRDownloader.cleanUp(days);

TODO

  • Integration with other libraries like OkHttp, RxJava
  • Test Cases
  • And of course many many features and bug fixes

If this library helps you in anyway, show your love ❤️ by putting a ⭐ on this project ✌️

License

   Copyright (C) 2022 Amit Shekhar

   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.

Contributing to PRDownloader

All pull requests are welcome, make sure to follow the contribution guidelines when you submit pull request.

prdownloader's People

Contributors

amitshekhariitbhu avatar anandgaurav10 avatar giangnt-arisvn avatar jyotid avatar shrgupt-microsoft avatar shrutigupta23 avatar subhrajyotisen avatar vinayagasundar avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

prdownloader's Issues

is it possible to know the name of the file on the disk while downloading ?

I am trying to implement caching and streaming of video using this library.
I do this by downloading the video file and give it a filename. But when downloading it has a different file name so i am unable to access the file during download. But when the download is successful I get it automatically renamed.

Max Number of parallel downloads

Hello,
What is the maximum number of parallel downloads ?
I have a scenario where I might need to download several files simultaneously .. However whenever I hit a certain number of running downloads, the next download will fire the error listener.

Thank you

Make errors more verbose

The Error class in PRDownloader is not really helping when debugging as it doesn't provide the issue that causes the download to fail.

I'd suggest adding a Throwable parameter to the Error class.

Thanks

Enhancement

Can we resume downloading a particular file with its changed remote path

Downloading stops Release mode only!

It works really great in debugging (Development) mode only!
The downloading process stops for the release version of the app!

I am getting these exceptions

java.io.IOException: write failed: EBADF (Bad file descriptor)
java.io.SyncFailedException: sync failed

Any help?

Thank you.

Server response type

hi

do you have any server service example ? Is prdownload support to chunk method ?

download stop when enable progurd

when i enable progurd
the realize apk has many error in downloading
but when peogurd is disabled problem solved
i ahould enable progurd for security
help me please .

A resource failed to call close.

When canceling or finishing a download, the error A resource failed to call close. is displayed.

How do we close the resource?

This happens only when .setDatabaseEnabled(false).

Fail when download some PDF files

When i'm trying to download several PDF file, some of them can't not download (size of file around 4-5mb) and return with errors. I'm using version 0.4.0.

#OnError download in lolipop version

Hi Bro,
when i used the lib i tested it with simple code which you show us ,it is working in M and O (versions( but i got "Error" when test downloading in lolipop
and i cant't know what is the Exception or the error type
please advice me

Error on resuming download

Hi and thanks for this great library.
i have problem with resuming download
in this test code with a simple activity download completed and paused successfully but resuming always caused error!!!

PRDownloader.initialize(getApplicationContext());
PRDownloaderConfig config = PRDownloaderConfig.newBuilder().setDatabaseEnabled(true).build();
PRDownloader.initialize(getApplicationContext(), config);

buttonDownload.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                downloadId = PRDownloader.download(url, dirPath, fileName).build()
                 .setOnStartOrResumeListener(new OnStartOrResumeListener() {
                    @Override
                    public void onStartOrResume() {
                        textStatus.setText("Preparing...");
                    }
                }).setOnPauseListener(new OnPauseListener() {
                    @Override
                    public void onPause() {
                        textStatus.setText("Paused");
                    }
                }).setOnCancelListener(new OnCancelListener() {
                    @Override
                    public void onCancel() {
                    }
                }).setOnProgressListener(new OnProgressListener() {
                    @Override
                    public void onProgress(Progress progress) {
                        textStatus.setText("Downloading...");
                        textPercent.setText((int) (100 * progress.currentBytes / progress.totalBytes) + "%");
                    }
                }).start(new OnDownloadListener() {
                    @Override
                    public void onDownloadComplete() {
                        textStatus.setText("Completed.");
                    }

                    @Override
                    public void onError(Error error) {
                        textStatus.setText("Error occurred!");
                    }
                });
            }
        });

buttonPause.setOnClickListener(new View.OnClickListener() {
         @Override
         public void onClick(View v) {
             PRDownloader.pause(downloadId);
          }
});

buttonResume.setOnClickListener(new View.OnClickListener() {
        @Override
         public void onClick(View v) {
             PRDownloader.resume(downloadId);
          }
});

(sorry for my bad english)

How to resume a download request after app restart

I'm trying to resume a download request after the app is killed.
I tried doing it by persisting the download Id like this

taskId = request!!.start(object : OnDownloadListener {
                override fun onDownloadComplete() {
                    Timber.d("Video completed!")
                    videoComplete = true
                    notifyComplete()
                }

                override fun onError(error: Error?) {
                    videoComplete = false
                    notifyError(error)
                }
            })

And then saving the taskId to a file.
After the app is restarted I retrieve the taskId from the file and use it like this:

PRDownloader.resume(taskId!!)

After debugging I figured out that the download request is null and therefore the request isn't resumed.

public void resume(int downloadId) {
        DownloadRequest request = currentRequestMap.get(downloadId);
        if (request != null) { // it's null!
            request.setStatus(Status.QUEUED);
            request.setFuture(Core.getInstance()
                    .getExecutorSupplier()
                    .forDownloadTasks()
                    .submit(new DownloadRunnable(request)));
        }
    }

Any help would be appreciated.
Thanks!

Corrupt file

Every time I download mp3 or jpg, it gets downloaded but is corrupted and I can not play it anywhere.
Is there anything I am missing.

PRDownloader.download("https://www.sample-videos.com/audio/mp3/wave.mp3",dirpath,"wave.mp3").build()
                            .start(new OnDownloadListener() {
                                @Override
                                public void onDownloadComplete() {
                                    Log.e("PRDownloader", "onDownloadComplete: ");
                                }

                                @Override
                                public void onError(Error error) {
                                    Log.e("PRDownloader", "onError: " + error.isConnectionError() + "    " + error.isServerError());
                                }
                            });

can you add more threads for one download mission?

recently, i used your source and read the all code which one mission with one thread for download, for more faster, i try to add some thread in the "DownloadTask",but face some trouble, so can you change the lib for supporting the multi-thread with one mission.<my english is bad,hope you understand>

NOT Working on Android 8.1

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        PRDownloader.initialize(getApplicationContext())
        val download_url = "https://images.pexels.com/photos/658687/pexels-photo-658687.jpeg?cs=srgb&dl=beautiful-bloom-blooming-658687.jpg"
      download(download_url)
}
fun downoad(url: String, fileName: String) {
        val dirPath = "/File Downloader/" + fileName
        val downloadId = PRDownloader.download(url, dirPath, fileName)
                .build()
                .setOnStartOrResumeListener {

                }
                .setOnPauseListener {}
                .setOnCancelListener {}
                .setOnProgressListener { progress ->

                    Log("Progress = ${((progress.currentBytes / progress.totalBytes) * 100) as Int}%")
                }
                .start(object : OnDownloadListener {
                    override fun onError(error: com.downloader.Error?) {
                        Log("onError. isServerError = ${error?.isServerError}. isConnectionError = ${error?.isConnectionError}")
                    }

                    override fun onDownloadComplete() {
                        Log("onDownloadComplete")
                    }
                })
    }```

How can change dirpath ?

Hello . I would like to thank you for this wonderful work and I have a question. How do I download files in a special folder such as My Pictures folder?

    dirPath = Utils.getRootDirPath(getApplicationContext());

Question about corePoolSize value.

Hi, I've been learning how to write a download library these days.
PRDownloader is nice, but codes written below confuse me.
https://github.com/MindorksOpenSource/PRDownloader/blob/6cc02b41443ed052a36e36d9c02e3ab32e10ca9f/prdownloader/src/main/java/com/downloader/core/DownloadExecutor.java#L34-L35
Setting the same value to corePoolSize and maximumPoolSize is not efficient , i think.
As reference, OkHttp do set corePoolSize to zero and maximumPoolSize to Interge.MAX_VALUE.
OkHttp Dispatcher

How can i download multiple files in one progress bar with download status

i want to download like when we download any game then supported files are being downloads with one progress bar and with total file counts alongwith current downloaded file status as same as QUEUED DOWNLOADING, so can i able to do this with this great library?
Hope this image clear my question:
queued_download

Download POST request

Thanks for the wonderful initiative.

Can this library support download for POST request (response as attachment/deposition) download header types?

Thank you.

Getting progress.totalBytes value as -1

I am facing an issue while working with this library, in callback onProgress(Progress progress) getting the value of progress.totalBytes as -1.

But the progress.currentBytes value is okay and also the download is working as expected.

Any idea why this is happening?

Multiple connections

I'd like to know how to implement multiconnections because with a single connection working at the download it downloads roughly at 1mb/s while as multiple would be normally 5 times the speed.

Request: Store object/value

Is there any built-in function to store object to the downloader and then can be retrieved back? (maybe pass it in listener callback)

Or is it for the sake of simplicity user must build this functionality by themselves outside the library?

Resume not working

I tried the same code as in demo but when I pause the button and resume again, this starts downloading from 0mb in .temp file

Download progress by downloadId

I want to start the download in one screen and I need the progress listeners on different screen by providing the downloadId. How can I get the download progress listener by downloadId .

Downloading data without extension

Hi,
it work for me very will but i have faced with a little issue which is downloaded data does not have any extension any idea how to solve this issue?

Download from recylerview

how to implement this downloader from recyclerview. faced issued due to downloadID. please provide example if possible.

Add support for Internal Storage file downloading

Hey!
I'm using internal storage in my app to save files and make them accessible for my app only. The problem is that onDownloadComplete() is never being called, even when the download is in fact complete.

The downloader is able to download the file inside Internal Storage but is not able to call onDownloadComplete() when it's done downloading.

App freeezing

It makes the button on my application screen to stop working

how to get download progress by downloadId

hi sir, this library is most useful for me, but i want show download progress in single progressbar according to user choice (means , user choose file name for view download progress), it is possible ?

Working With Fragments

This is more of a Question than an issue.
I'm working with Fragments and using this library in one fragment(downloads),
I'm handling download/pause button clicks inside an Adapter Class, If I download a file it displays the progressbar and filesize correctly, but if I go to another fragment and return back to the downloads fragment the progressbar is gone and also the pause button is now displayed as start download button.
Is there any way to tell if I'm in the downloads fragment any not reset the layout of the fragment or can we use a background service with the library and maybe instead of displaying the information on the Screen, we will display the download progress in the notification area.

Download keeps calling onError

Hello.
I'm trying to use PRDownloader in my app and each time I try to download a video file it just calls onError().
Here is my code:

                            Uri uri = Uri.parse(videoURL);
                            String subPath = URLUtil.guessFileName(uri.toString(), null, null);
                            subPath = subPath.replaceAll("-","");
                            int downloadID =PRDownloader.download(videoURL,"some/directory/"
                                    ,subPath.substring(0,subPath.length()-4) +".dat")
                                    .build()
                                    .setOnStartOrResumeListener(new OnStartOrResumeListener() {
                                        @Override
                                        public void onStartOrResume() {
                                            Log.d("Download","onStartOrResume" );
                                        }
                                    })
                                    .setOnPauseListener(new OnPauseListener() {
                                        @Override
                                        public void onPause() {
                                            Log.d("Download","onPause" );
                                        }
                                    })
                                    .setOnCancelListener(new OnCancelListener() {
                                        @Override
                                        public void onCancel() {
                                            Log.d("Download","onCancel" );
                                        }
                                    })
                                    .setOnProgressListener(new OnProgressListener() {
                                        @Override
                                        public void onProgress(Progress progress) {
                                            Log.d("Download","Progress: " + progress);
                                        }
                                    })
                                    .start(new OnDownloadListener() {
                                        @Override
                                        public void onDownloadComplete() {
                                            Log.d("Download","Complete");
                                        }

                                        @Override
                                        public void onError(Error error) {
                                            Log.d("Download","Error "+error);
                                        }
                                    });

videoURL is a valid url from amazon CDN.
I've tried to download the video with my browser and it downloads successfully but not in my app.

PRDownloader Not Working on API 17!

I ran the code on API 17. it's not working @amitshekhariitbhu, @janishar , @aamir2590, @doersweb, @balsikandar

here's my code -> https://github.com/Edge-Developer/PRDownloader_Bug/blob/master/app/src/main/java/com/edgedevstudio/test/MainActivity.kt

class MainActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    PRDownloader.initialize(getApplicationContext())
    val url = "http://www.alexszepietowski.com/wp-content/uploads/downloads/2013/03/The 2 Golden Rules of Property, Business and Life!.pdf"
    val fileName = "MyFile.pdf"
    val dirPath = "/File Downloader/PDF/$fileName"
    val downloadId = PRDownloader.download(url, dirPath, fileName)
            .build()
            .setOnStartOrResumeListener {  Log("OnStartOrResumeListener. onStartOrResume")}
            .setOnPauseListener { }
            .setOnCancelListener{ Log("OnCancelListener. onCancel")}

            .setOnProgressListener {
                Log("Progress = ${((it.currentBytes / it.totalBytes) * 100)}%")
            }
            .start(object : OnDownloadListener {
                override fun onDownloadComplete() {
                    Log("OnDownloadListener. onDownloadComplete")
                }

                override fun onError(error: Error) {
                    Log("onError. isConnectionError = ${error.isConnectionError}, isServerError = ${error.isServerError}")

                }
            })
    Log("onCreate, DownloadId = $downloadId")
}
fun Log(msg : String){
    Log.d("MainActivity", msg)
}
}
```


Here's my log output



```
09-03 18:21:23.759 D/MainActivity: onCreate, DownloadId = 1621365470

09-03 18:21:26.389 D/MainActivity: OnStartOrResumeListener. onStartOrResume

09-03 18:21:26.389 D/MainActivity: onError. isConnectionError = true, isServerError = false
```

MANIFEST

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

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>
```

Resume Download

Hi,
How to resume download after closing app (destroying activity ) and opening it again?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.