-
-
Notifications
You must be signed in to change notification settings - Fork 694
4.x Usage
- HTTP multipart/form-data upload
- HTTP binary upload
- FTP upload
- Persistent upload requests
- Management APIs. Programmatically get running uploads and stop them
- Multiple uploads
All the upload requests are non blocking. They trigger a background upload service, so you can fire requests directly from your fragments, activities or services without concerns.
All the examples are in Kotlin, but the library is 100% interoperable with Java, so you can have the same functionality (with a slightly different syntax) even if you have 100% Java codebase, without worries.
If you know Java and want to learn Kotlin, this will get you up to speed: https://developer.android.com/kotlin/learn-kotlin-java-pathway
When you create an upload request and call startUpload()
, you will get a unique string which identifies the upload task. Using that string you can monitor the upload or stop it using Management APIs.
If you need it, you can generate an upload ID yourself and set it in the upload request by calling .setUploadID("yourID")
before startUpload()
. When doing that, be careful to always generate unique strings to avoid problems.
HTTP multipart/form-data upload (RFC2388)
When in trouble, follow the troubleshooting procedure
This is the most common way to upload files on a server. It's the same kind of request that browsers do when you use the <form>
tag with one or more files. Here's a minimal example:
MultipartUploadRequest(context, serverUrl = "https://my.server.com")
.setMethod("POST")
.addFileToUpload(
filePath = filePath,
parameterName = "myFile"
).startUpload()
Check the other methods available in MultipartUploadRequest class and their docs. You can also add multiple headers, files and parameters. To monitor upload progress and status, check: https://github.com/gotev/android-upload-service/wiki/Monitor-Uploads
By default, the global notification configuration and retry policy will be applied. You can override both in each request using
setNotificationConfig
andsetMaxRetries
methods.
feature | description |
---|---|
multiple files in a single request | yes. There are many ways to do it. Example. |
support for HTTP Basic and Bearer Auth | yes. Add .setBasicAuth("username", "password") or .setBearerAuth("bearer-token") when you build the request |
add custom request headers | yes. You can also set them with request interceptors if you are using OkHttp stack. |
add custom request parameters | yes |
default charset | UTF-8. Non latin characters are supported out of the box. |
resuming uploads | no. If an upload fails at some point, the temporary data will be discarded automatically by your server and the upload will start from the beginning on the next request. The server sees a multipart request as a single stream of data, as per RFC specs. There's no way to resume a multipart upload. You have to start over. |
When in trouble, follow the troubleshooting procedure
The binary upload uses a single file as the raw body of the upload request. Here's a minimal example:
BinaryUploadRequest(context, serverUrl = "https://my.server.com")
.setMethod("POST")
.setFileToUpload(filePath)
.startUpload()
Check the other methods available in BinaryUploadRequest class and their docs. You can also add multiple headers. To monitor upload progress and status, check: https://github.com/gotev/android-upload-service/wiki/Monitor-Uploads
By default, the global notification configuration and retry policy will be applied. You can override both in each request using
setNotificationConfig
andsetMaxRetries
methods.
feature | description |
---|---|
multiple files in a single request | no. Only one file per request, which will be in the request body. It is more bandwidth efficient than HTTP/Multipart if all you need is to upload only one file to a server, without passing additional data in the request. If you want to pass the original file name to your server using this kind of request, the only way you can do it is by setting a custom header. Bear in mind that HTTP headers are encoded in US-ASCII, so don't use non-latin values. |
support for HTTP Basic and Bearer Auth | yes. Add .setBasicAuth("username", "password") or .setBearerAuth("bearer-token") when you build the request |
add custom request headers | yes. You can also set them with request interceptors if you are using OkHttp stack. |
add custom request parameters | no, the request body consists only of the selected file to upload. There's no room for parameters like multipart requests. Calling addParameter and addArrayParameter methods will have no effect and you'll see a log message. |
default charset | US-ASCII. UTF-8 is not supported because you can only set request headers, which must be in US-ASCII encoding |
resuming uploads | no. If an upload fails at some point, the temporary data will be discarded automatically by your server and the upload will start from the beginning on the next request. The server sees the request as a single stream of data. There's no way to resume a binary upload. You have to start over. |
Starting from version 4.5.0
it's possible to serialize and deserialize upload requests, to be able to save them persistently and run them later.
All the Upload Requests (Multipart, binary, FTP and also custom ones) have the method .toPersistableData()
which creates a PersistableData
object containing all the necessary data to recreate the upload request later. PersistableData
is Parcelable
and can also be converted to a standard android Bundle
or a JSON string. The JSON string version is not meant to be human readable, but a convenient way to pass complex structured data using a string.
To recreate a request from serialized data:
val request = CreateUploadRequest.fromPersistableData(context, persistableData)
val requestFromJson = CreateUploadRequest.fromJson(context, jsonString)
val requestFromParcel = CreateUploadRequest.fromParcel(context, parcel)
UploadNotificationConfig
is not included in the serialized form because it's not serializable, as it may contain PendingIntents
used for notification actions and Bitmap
icons. When you recreate the request using CreateUploadRequest
, UploadServiceConfig.notificationConfigFactory
is used automatically to get an UploadNotificationConfig
, which you can override before starting the upload using the setNotificationConfig
method.
val multipartUploadData = MultipartUploadRequest(context, "https://my.server.com")
.addFileToUpload(
filePath = "/path/to/file",
parameterName = "file",
fileName = "testing",
contentType = "application/octet-stream"
).toPersistableData()
CreateUploadRequest.fromPersistableData(context, multipartUploadData).startUpload()
val jsonData = BinaryUploadRequest(context, "https://my.server.com")
.setFileToUpload("/path/to/file")
.addHeader(
headerName = "headerName",
headerValue = "headerValue"
).toPersistableData().toJson()
CreateUploadRequest.fromJson(context, jsonData).startUpload()
val parcel = Parcel.obtain()
BinaryUploadRequest(context, "https://my.server.com")
.setFileToUpload("/path/to/file")
.addHeader(
headerName = "headerName",
headerValue = "headerValue"
).toPersistableData().writeToParcel(parcel, 0)
parcel.setDataPosition(0)
CreateUploadRequest.fromParcel(context, parcel).startUpload()
val ftpData = FTPUploadRequest(context, "https:://my.server.url", 1234)
.addFileToUpload(
filePath = "/path/to/file",
remotePath = "/remote/path",
permissions = UnixPermissions("644")
)
.setConnectTimeout(2000)
.setSocketTimeout(10000)
.setCreatedDirectoriesPermissions(UnixPermissions("777"))
.useSSL(true)
.setSecureSocketProtocol("TLS")
.setUsernameAndPassword(username = "user", password = "pass")
.setSecurityModeImplicit(true)
.useCompressedFileTransferMode(true)
.setMaxRetries(2)
.toPersistableData()
CreateUploadRequest.fromPersistableData(context, ftpData).startUpload()
You can call the following methods from anywhere you want in your code.
Method | Description |
---|---|
UploadService.taskList |
Gets all the currently active upload tasks |
UploadService.stopAllUploads() |
Stops all the active upload tasks. Listening RequestObserver's onError method will be fired with UserCancelledUploadException for each upload you are monitoring. |
UploadService.stopUpload(uploadId) |
Stops a specific upload task. Listening RequestObserver's onError method will be fired with UserCancelledUploadException
|
UploadService.stop(context) |
Stops UploadService if no tasks are currently running. It returns a boolean which indicates if the service is shutting down. |
UploadService.stop(context, forceStop = true) |
Force stops UploadService aborting any currently running tasks. It calls stopAllUploads() and returns a boolean which indicates if the service is shutting down. |
In some cases you want to upload several files to your server at once. You have the following options:
- Add many files to a single upload request (supported in Multipart and FTP Upload Request)
- Create an upload request for each file
We assume this is the list of files to upload:
val files = listOf(
"/path/to/my/files/file1.png",
"/path/to/my/files/file2.png",
"/path/to/my/files/file3.png"
)
In this case you may want to tune the number of parallel uploads: https://github.com/gotev/android-upload-service/wiki/Configuration#number-of-parallel-uploads
files.forEach { file ->
MultipartUploadRequest(context, serverUrl = "https://my.server.com")
.addFileToUpload(file, parameterName = "file")
.startUpload()
}
files.forEach { file ->
BinaryUploadRequest(context, serverUrl = "https://my.server.com")
.setFileToUpload(file)
.startUpload()
}
MultipartUploadRequest(context, serverUrl = "https://my.server.com").apply {
files.forEach { file ->
addFileToUpload(file, parameterName = "files[]")
}
}.startUpload()
in this case the parameterName
used is files[]
because it's a common standard which indicates an array of files with the same parameter name. For example, PHP has an out of the box support for this kind of uploads. This may vary based on the server-side technology you're using. Use what's appropriate for you. Listing all the available standards is beyond the scope of this library and this example.