Skip to main content

Autoupload

Start Autoupload#

The Photos SDK starts auto-upload automatically when all necessary conditions are met and stops when some of them are not met. If some of the conditions are not met initially, auto-upload never starts until all of them are fixed. The list of reasons, which are currently preventing auto-upload from starting can be retrieved from UploadStatus, see Monitor Autoupload Status

Basically, to start auto-upload, the following actions should be taken:

Autoupload Settings#

The autoupload configuration has the following fields and default values:

// Auto upload on/offisAutoUploadEnabled = false
// Cellular data upload allowedis3gUploadEnabled = false
// Minimum battery charge for auto uploadminBatteryLevel = 0.0f
// Video upload allowedisVideoUploadEnabled = false
// Roaming upload allowedisRoamingUploadEnabled = false
// The maximum number of attempts to upload a photo/video file to the cloud.// If 0, then the number of attempts is not limited. If 1 - only one attempt is given, etc.maxRetryCount = 0
// If true, photos will be uploaded first, then videos. If false, the priority is not defined.isPhotosFirst = false

To change a configuration, call the following method:

PhotoManager.uploadManager.config =    PhotoManager.uploadManager.config.copy(            minBatteryLevel = 0.3f        )

Links - UploadConfig.

Monitor Autoupload Status#

The autoupload status allows you to monitor the autoupload process, as well as receive information regarding the interruptios in work. To get the status, call the following method:

var disposable: Disposable? = null
// ...
// You have to subscribe to the returned Observable in order to receive updates.disposable = PhotoManager.uploadManager.getStatusObservable()        .observeOn(AndroidSchedulers.mainThread())        .subscribe { // it: UploadStatus!            uploadStatusView.text = it.photosLeft.toString()        }
// ...
// You must call dispose() on disposable that returned by subscribe() method,// when it is no longer needed, for example in your fragment’s onStop() or onPause().disposable?.dispose()

The PhotoManager.uploadManager.getStatusObservable() method returns Observable, which emits a new status object every time a change during autoupload occurs. The status object has the following properties:

data class UploadStatus(
    /** Auto-upload status.  */    val status: Status,
    /** List of reasons why auto-upload was paused. If empty - uploading is on the run.  */    val reasons: List<Reason>,
    /** Total photos (backend+local) in the timeline */    val totalPhotos: Int,
    /** Number of photos uploaded from this device. */    val photosUploaded: Int,
    /** Number of photos to upload. */    val photosLeft: Int
) {    enum class Status {
        /** Photos are being uploaded or uploading finished (if photosLeft==0)  */        UPLOADING,
        /** Uploading process is paused. See reasons. */        PAUSED,    }
    enum class Reason {        /** Backend gallery has not been read yet */        BACKEND_NOT_READ,
        /** Local gallery has not been read yet */        LOCAL_GALLERY_NOT_READ,
        /** Apps negotiating about which one will be responsible for uploading photos to the cloud */        COMPETITION_NOT_FINISHED,
        /** Another app is responsible for uploading to the cloud. This app will not upload. */        ANOTHER_APP_INSTALLED,
        /** Auto upload is disabled in upload configuration */        AUTO_UPLOAD_DISABLED,
        /** READ_EXTERNAL_STORAGE permission has not been granted */        STORAGE_PERMISSION_NOT_GRANTED,                /** No internet connection */        NO_CONNECTION,                /** No Wi-Fi connection, but the use of mobile network is prohibited */        NO_CONNECTION_WIFI,                /** Not enough battery level to continue auto-upload */        LOW_BATTERY,                /** User does not have enough space in the cloud storage */        LOW_CLOUD_STORAGE,                /** Auth token has been expired. App need to re-login user. */        TOKEN_EXPIRED,                /** SDK is being logged out */        LOGGING_OUT,    }}

The main fields are status and reasons. The status field can contain:

  • UPLOADING - autoupload is being executed (in this case the field reasons contains an empty list). status field is UPLOADING even if there are no media to upload. When new photo/video is taken it will be uploaded automatically.
  • PAUSED - autoupload is paused for some reason. The reasons field contains a list of reasons why the autoupload is paused. For example:[AUTO_UPLOAD_DISABLED, LOW_BATTERY] means that autoupload is disabled in the configuration and in addition, low battery prevents autoupload. For more details, see Start Autoupload.

After the backend gallery and the local gallery are read, if there is no other reason for delay, autoupload starts automatically. For more details, see Autoupload Settings

Ongoing Notification#

In order for the system not to kill the application while uploading the photos to the cloud (especially when the application is not active and works in the background), the Photo SDK launches the foreground service and displays an ongoing notification. The application is responsible for preparing the UI of this notification, since only this application has all the necessary resources.

The interaction is as follows:

  • The Photos SDK declares interface UploadNotificationAdapter
  • The application implements this interface and sets the implementation to the SDK using PhotoManager.upload.setNotificationAdapter(adapter) .
  • The SDK calls the application's implementation every time when upload status is changed.
  • Application returns a new notification object on each call.

The interface has the following specifications:

interface UploadNotificationAdapter {    fun statusToNotification(uploadStatus: UploadStatus): Notification}

The method statusToNotification receives the upload status and returns a ready notification displayed by the foreground service from the Photos SDK. The statusToNotification ()method is called each time the upload status is changed.

Also, the application must independently register a message channel on Android 8+.

The format of intents sent between the Photos SDK instances#

Below is an example of sending a message from Standalone to Integration (request to stop auto upload):

Intent().also {    it.action = "com.cloudike.cloudikephotos.Competition.StopUpload"    it.`package` = "<integration_app_package_id>"    context.sendBroadcast(it)}

In the package field, you must specify the package-id of the second application, in this case the one that works in the Integration mode. Otherwise, the intent will not be sent to the address, but to all applications, which may affect the operation of other applications using the Photos SDK.

An example of sending confirmation from Integration to Standalone (auto upload is stopped):

Intent().also {    it.action = "com.cloudike.cloudikephotos.Competition.CompetitorStoppedUpload"    it.`package` = "<standalone_app_package_id>"    context.sendBroadcast(it)}

In the package field, you must specify the package-id of the second application, in this case the one that works in the Standalone mode. Otherwise, the intent will not be sent to the address, but to all applications, which may affect the operation of other applications using the Photos SDK.