GDownload
Light Weight, Fast 🚀 , Easy to Use, Reliable Download client for android.
Install / Use
/learn @tanoDxyz/GDownloadREADME
Overview
GDownload is a simple, powerful, easy to use, customizable file download client library for Android.

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.
- Download Elapsed time reporting.
- Save and Retrieve download information anytime.
- Scope Storage 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"
android:maxSdkVersion="28" />
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 GDownload
Using GDownload is easy! Just add the following to your application's root build.gradle file.
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
And then add the dependency to the module level build.gradle file.
implementation 'com.github.tanoDxyz:GDownload:1.2'
Initalization
Although! library can be used independently without initalization but initalization gives us two benefits.
First, it will reuse the existing downloaders from the pool if available.
Second, if the app is closed and the user wants to stop all the downloads running this will help out.
GDownload.init(lifecycle) //activity.lifecycle or any other lifecycle // could be null too
The above line will initalize the library and if the non null Lifecycle
is passed the library will terminate all the running or paused downloads when
the lifecycle is destroyed.
Single Download
First Way
Make sure you called GDownload.init(Lifecycle) and then
Inside Activity or Fragment call the following method.
Remember if the argument passed is Activity or Fragment.
DownloadProgressListener callbacks will be called only when the Activity or Fragment is visible.
GDownload.singleDownload(Activity or Fragment or Context) {
url = "url"
name = "fileName or FilePath"
downloadProgressListener = object :DownloadProgressListener {
override fun onConnectionEstablished(downloadInfo: DownloadInfo?) {}
override fun onDownloadProgress(downloadInfo: DownloadInfo?) {}
override fun onDownloadFailed(downloadInfo: DownloadInfo, ex: String) {}
override fun onDownloadSuccess(downloadInfo: DownloadInfo) {}
override fun onDownloadIsMultiConnection(
downloadInfo: DownloadInfo,
multiConnection: Boolean
) {}
override fun onPause(downloadInfo: DownloadInfo, paused: Boolean, reason: String) {}
override fun onRestart(
downloadInfo: DownloadInfo,
restarted: Boolean,
reason: String
) {}
override fun onResume(downloadInfo: DownloadInfo, resume: Boolean, reason: String) {}
override fun onStop(downloadInfo: DownloadInfo, stopped: Boolean, reason: String) {}
}
}
This method GDownload.singleDownload supports the following attributes.
| Property | Definition |
| ------------- |:-------------:|
| url* | resource address |
| name* | file name or absolute filePath |
| downloadCallbacksOnMainThread | Flag indicating which thread to use for download progress callbacks |
| connectionFactory | connection Factory used to make connections to the remote server |
| downloadFilesRoot | optional root path that will be used for saving files. if name argument is absolute path it always take precedence if both are present. |
| networkType | network type to use for downloading. |
| connectionRetryCount | number of times connection factory will try to establish a connection in case of failures. |
| maxNumberOfConnections | number of concurrent connections(threads). max 32 |
| progressUpdateTimeMilliSec | interval difference between consective calls of onDownloadProgress method in DownloadProgressListener |
| getDownloader() | retrieve the download manager associated with the download |
| downloadProgressListener | Download progress Listener. |
Second Way
Make sure you called GDownload.init(Lifecycle) and then call the following method.
GDownload.freeDownloader(Context) { downloader ->
downloader.download(
"url",
"name",
NetworkType.ALL,
object : DownloadProgressListener {
override fun onDownloadSuccess(downloadInfo: DownloadInfo) {}
override fun onDownloadFailed(downloadInfo: DownloadInfo, ex: String) {}
})
}
Third Way
For this way of downloading you don't need to initalize anything.
Simply call the following
val downloader = GDownload.freeDownloader(
Context,
ScheduledBackgroundExecutor,
DownloadCallbacksHandler,
FileStorageHelper,
ConnectionManager,
DownloadDatabaseManager,
NetworkInfoProvider
)
downloader.download("url", "name", NetworkType.ALL, object : DownloadProgressListener {})
Pause Download
To pause a download is pretty simple.
downloader.freezeDownload {frozen,msg ->
if(frozen) {
//download froze/paused
}else {
// $msg indicates the reason
}
}
Remember when this method is called DownloadProgressListener onPause() is also invoked.
Stop Download
To stop a download is pretty simple.
downloader.stopDownload {stopped,msg ->
if(stopped) {
//download stopped
}else {
// $msg indicates the reason
}
}
Remember when this method is called DownloadProgressListener onStop() is also invoked.
Difference b/w Pause and Stop
Pause and Stop does the same job - just stop the download.
The difference lies in a fact that Pause Park Threads after download is stopped and later when resume is called, these threads will be used.
While stop don't park threads.
Resume Download
Download that is paused can be resumed like this.
downloader.resumeDownload {resumed, msg->
if(resumed) {
// download successfully resumed
}else {
// check the $msg
}
}
Restart Download
Download that is 'Stopped' or Failed can be restarted via
downloader.restart {restarted, msg->
if(restarted) {
// download successfully restarted
}else {
// check the $msg
}
}
Load Failed Downloads From Database
First way
Make sure you called GDownload.init() and then call use the following method
GDownload.loadAllInCompleteDownloadsFromDatabase(Context) {downloadList->
// process downloads
downloadList.forEach { download ->
GDownload.freeDownloader(Context) {
it.download(download, object : DownloadProgressListener {})
}
}
}
Second way
val dbManager = SQLiteManager.getInstance(Context)
dbManager.findDownloadByDownloadId(downloadId_int)
val allInCompleteDownloads = dbManager.findAllInCompleteDownloads()
dbManager.findDownloadByFilePath("filePath")
dbManager.close()
Third way
If you had reference to the downloader then you can directly load the failed download from database.
downloader.loadDownloadFromDatabase(DownloadID) {loaded->}
downloader.loadDownloadFromDatabase("filePath") {loaded->}
Fourth way
if you had reference to the GroupProcessor(Group) then you can directly load the failed download/s from database into the group processor.
group.loadDownloadsFromDatabase {downloadsEnqueued -> }
Shutdown Downloader
If you want to shutdown downloader and it's best practice.
just call
downloader.shutdown()
Group Download
In Order to Download Multiple files and monitor them as a single entity,
GroupDownloader can be used.
There are various ways to create one.
Make sure you called GDownload.init(Lifecycle) and then
val downloadList = mutableListOf<Download>()
GDownload.freeGroup(Context) {
groupLoopTimeMilliSecs = 5_00
getGroup()?.apply {
start() // start group thread. as group has it's dedicated thread
addAll(downloadList) { // enqueue downloads in the group but don't issue the start command
startDownloads(it) // start group downloads
}
addGroupProgressListener(GroupListener)
}
}
see sample app for more details. The following attributes are supported for group downloa
Related Skills
node-connect
340.5kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
84.2kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
340.5kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
commit-push-pr
84.2kCommit, push, and open a PR

