Skip to main content

Working With Albums

This guide describes methods for working with albums. The guide is logically divided into two parts - Album Actions and Album Content Actions.

Album Actions#

This chapter describes methods for creating and modifying albums, excluding working with their contents.

Read Album List From Backend#

To get started with the albums, first of all get information about the family albums from the backend.

important

Since the download procedure takes some time (and, on the other hand, does not require permission from the user), it should be started as soon as the user is logged into the application.

To download the list of albums from the backend, use the following code example.

var disposable: Disposable? = null
// ...
// The returned Completable emits a completion when the read album list operation is completed.// You have to subscribe on returned completable in order to receive updates.disposable = PhotoManager.albums.reloadAlbumList()        .observeOn(AndroidSchedulers.mainThread())        .subscribeBy(                onComplete = {                    // Handle it                },                onError = { // it: Throwable                    // Handle it                }        )
// ...
// You must call dispose() on disposable that returned by subscribe() method,// when it no longer needed, for example in your fragment’s onStop() or onPause().disposable?.dispose()

Get Albums List#

The Photos SDK provides information about albums for the client application as a paged list of AlbumItem objects.

The createPagingAlbumsObservable() function creates new Observable that emits a PagingData of AlbumItems every time there is a change to the local database. To display the paginated list in the RecyclerView, you must use PagingDataAdapter from the Android Paging Library.

The Cloudike Photos SDK uses the following Android Paging Library.

// Pagingimplementation 'androidx.paging:paging-runtime-ktx:3.1.1'implementation 'androidx.paging:paging-rxjava2-ktx:3.1.1'

The following code example demonstrates getting a list of albums.

class AlbumListViewModel(    private val albums: Albums) : ViewModel() {
    // NOTE: Your app can use either Observable or Flow. Both of them are created here for demo purposes only.        val contentObservable: Observable<PagingData<AlbumItem>> by lazy {        albums.createPagingAlbumsObservable()            .cachedIn(viewModelScope)    }
    val contentFlow: Flow<PagingData<AlbumItem>> by lazy {        albums.createPagingAlbumsFlow()            .cachedIn(viewModelScope)    }}
// Factory is required to pass albums to the view modelclass AlbumListViewModelFactory(    private val albums: Albums) : ViewModelProvider.NewInstanceFactory() {
    override fun <T : ViewModel> create(modelClass: Class<T>): T {        return AlbumListViewModel(albums) as T    }}
// Fragmentclass AlbumListFrg : Fragment() {
    private val adapter: AlbumListAdapter // derived from PagingDataAdapter    private val albums = PhotoManager.albums    private val viewModel: AlbumListViewModel by viewModels { AlbumListViewModelFactory(albums) }    private var disposable: Disposable? = null
    override fun onStart() {        super.onStart()        // You have to subscribe to the returned Observable to receive updates.        disposable = viewModel.contentObservable            .subscribe { pagingData ->                // Update adapter                adapter.submitData(this.lifecycle, pagingData)            }    }
    override fun onStop() {        super.onStop()        // You must call dispose() on disposable that returned by the subscribe() method,        // when it is no longer needed, for example in your fragment’s onStop() or onPause().        disposable?.dispose()    }}

As an alternative to Observable, Flow is also available for getting list of albums:

    override fun onStart() {        super.onStart()        lifecycleScope.launch {            viewModel.contentFlow                .collectLatest {                    adapter.submitData(it)                }        }    }

Links - PagingData, AlbumItem, AlbumType, OperationEditAlbum.

Get Album#

The following code example demonstrates getting an album.

var disposable: Disposable? = null
// Album name.val albumId: String = // "id"
// ...
// The returned Single emits an AlbumItem when the getting album operation is succeeded.// You have to subscribe to returned single in order to receive result.disposable = PhotoManager.albums.getAlbumItem(albumId)        .observeOn(AndroidSchedulers.mainThread())        .subscribeBy(                onSuccess = { // it: AlbumItem!                    // Handle it                },                onError = { // it: Throwable                    // Handle it                }        )
// ...
// 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()

Links - AlbumItem.

Create Album#

The following code example demonstrates creating an album.

var disposable: Disposable? = null
// Album name.val description: String = "Description"
// Album type.val type: AlbumType = AlbumItem.AlbumType.SIMPLE// Album can be one of the following types://     * SIMPLE - Simple album.//     * SHARED - Album that has a link for viewing and / or editing//                (depending on the isSharedForEdit parameter).

// If true, the album can be edited by accessing the link.val isShareForEdit: Boolean = false
// List of photos to add to the new album. If the photos / videos specified for adding to // the album have not yet been uploaded to the cloud storage, then they will be // automatically uploaded first, and only then added to the album. Uploading to cloud // storage may take a while, depending on the amount of data.val photoList: List<PhotoItem> = listOf()
// ...
// Returns an OperationCreateAlbum object from which information about the operation can be // obtained. For example, to know about the completion of an operation, you need to // subscribe to the single included in the operation object.disposable = PhotoManager.albums.operations        .createAlbum(description, type, isShareForEdit, photoList)        .single        .observeOn(AndroidSchedulers.mainThread())        .subscribeBy(                onSuccess = { // it: AlbumItem!                    // Handle it                },                onError = { // it: Throwable                    // Handle it                }        )
// ...
// 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()

Links - AlbumType, PhotoItem, OperationCreateAlbum.

Edit Album#

The following code example demonstrates editing an album.

var disposable: Disposable? = null
// Album id.val albumId: String = "Description"
// Description of album.val description: String = "Description"
// Album type.val type: AlbumType = AlbumItem.AlbumType.SIMPLE// Album can be one of the following types://     * SIMPLE - Simple album.//     * SHARED - Album that has a link for viewing and / or editing//                (depending on the isSharedForEdit parameter).
// If true, the album can be edited by accessing the link.val isShareForEdit: Boolean = false
// ...
// Returns an OperationEditAlbum object from which information about the operation can be // obtained. For example, to know about the completion of an operation, you need to // subscribe to the single included in the operation object.disposable = PhotoManager.albums.operations        .editAlbum(albumId, description, type, isShareForEdit)        .single        .observeOn(AndroidSchedulers.mainThread())        .subscribeBy(                onSuccess = { // it: AlbumItem!                    // Handle it                },                onError = { // it: Throwable                    // Handle it                }        )
// ...
// 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()

Links - AlbumType, OperationEditAlbum.

Delete Album#

Sample code for deleting albums:

var disposable: Disposable? = null
// List of album IDs to be deleted. When you delete an album, the photos and videos included in it are not deleted, and are still available in the Timeline.val albumIdList: List<String> = listOf()
// ...
// Returns an OperationDeleteAlbums object from which information about the operation can be // obtained. For example, to know about the completion of an operation, you need to // subscribe to the single included in the operation object.disposable = PhotoManager.albums.operations        .deleteAlbums(albumIdList)        .completable        .observeOn(AndroidSchedulers.mainThread())        .subscribeBy(                onComplete = {                    // Handle it                },                onError = { // it: Throwable                    // Handle it                }        )
// ...
// 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()

Links - OperationDeleteAlbums.

Album Content Actions#

This chapter describes methods for creating and modifying albums, excluding working with their contents.

Read Album Content From Backend#

To get started with album content, download the actual content from the backend (list of photos in the album).

var disposable: Disposable? = null
// Album ID. It can be obtained from AlbumItem.val albumId: String = // Some "Id"
// If true, then a full reading of the list of photos and videos from the backend is // performed. This can take a long time. If false, then reading is performed incrementally, // only the last changes are read.val fullRefresh: Boolean = false
// ...
// You have to subscribe to returned observable in order to receive updates.disposable = PhotoManager.albums.reloadAlbumContent(albumId, fullRefresh)        .observeOn(AndroidSchedulers.mainThread())        .subscribeBy(                onSuccess = { // it: AlbumItem!                    // Handle it                },                onError = { // it: Throwable                    // Handle it                }        )
// ...
// 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()

Links - AlbumItem.

Get Album Content#

The Cloudike Photos SDK provides information about photos and videos of an album to the client application as a paged list of PhotoItem objects. Working with this list is similar to the Timeline.

important

The createPagingAlbumContentObservable(albumId) function creates new Observable that emits a PagingData of PhotoItems every time there is a change to the local database. To display the paginated list in the RecyclerView, you must use PagingDataAdapter from the Android Paging Library.

The Cloudike Photos SDK uses the following Android Paging Library.

// Pagingimplementation 'androidx.paging:paging-runtime-ktx:3.1.1'implementation 'androidx.paging:paging-rxjava2-ktx:3.1.1'

The following code example demonstrates getting an album content.

// Declare view modelclass AlbumViewModel(    private val albumId: String,    private val albums: Albums) : ViewModel() {
    // NOTE: Your app can use either Observable or Flow. Both of them are created here for demo purposes only.        val contentObservable: Observable<PagingData<PhotoItem>> by lazy {        albums.createPagingAlbumContentObservable(albumId)            .cachedIn(viewModelScope)    }
    val contentFlow: Flow<PagingData<PhotoItem>> by lazy {        albums.createPagingAlbumContentFlow(albumId)            .cachedIn(viewModelScope)    }}
// Factory is required to pass albumId and albums singleton to the view modelprivate class AlbumViewModelFactory(    private val albumId: String,    private val albums: Albums) : ViewModelProvider.NewInstanceFactory() {
    override fun <T : ViewModel> create(modelClass: Class<T>): T {        return AlbumViewModel(albumId, albums) as T    }}
// Fragmentclass AlbumFrg : Fragment() {
    private lateinit var albumId: String    private val adapter: AlbumAdapter // derived from PagingDataAdapter    private val albums = PhotoManager.albums    private val viewModel: AlbumViewModel by viewModels { AlbumViewModelFactory(albumId, albums) }    private var disposable: Disposable? = null
    override fun onStart() {        super.onStart()        // You have to subscribe to the returned Observable to receive updates.        disposable = viewModel.contentObservable            .subscribe { pagingData ->                // Update adapter                adapter.submitData(this.lifecycle, pagingData)            }    }
    override fun onStop() {        super.onStop()        // You must call dispose() on disposable that returned by the subscribe() method,        // when it is no longer needed, for example in your fragment’s onStop() or onPause().        disposable?.dispose()    }}

As an alternative to Observable, Flow is also available for getting media items of the album:

    override fun onStart() {        super.onStart()        lifecycleScope.launch {            viewModel.contentFlow                .collectLatest {                    adapter.submitData(it)                }        }    }

Links - PagingData, PhotoItem.

Add Photos To Album#

To add a photo / video to an existing album, use the PhotoManager.albums.operations.addPhotos() function.

important

The same photo / video can be added to multiple albums.

important

If the photos / videos specified for adding to the album have not yet been uploaded to the cloud storage, then they will be automatically uploaded first, and only then added to the album. Uploading to cloud storage may take a while, depending on the amount of data.

The following code example demonstrates adding a photo to an album.

var disposable: Disposable? = null
// Album ID. It can be obtained from AlbumItem.val albumId: String = "Id"
// List of photos / videos to add to the album.val photoList: List<PhotoItem> = listOf()
// ...
// Returns an OperationAddPhotos object from which information about the operation can be // obtained. For example, to know about the completion of an operation, you need to // subscribe to the single included in the operation object.disposable = PhotoManager.albums.operations        .addPhotos(albumId, photoList)        .single        .observeOn(AndroidSchedulers.mainThread())        .subscribeBy(                onSuccess = { // it: AlbumItem!                    // Handle it                },                onError = { // it: Throwable                    // Handle it                }        )
// ...
// 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()

Links - PhotoItem, OperationAddPhotos.

Remove Photos From Album#

To remove a photo / video from the existing album, use the PhotoManager.albums.operations.removePhotos () function.

important

When you delete items from an album, they are not deleted from the cloud storage, and will still be available in the Timeline.

var disposable: Disposable? = null
// Album ID. It can be obtained from AlbumItem.val albumId: String = "Id"
// List of photos / videos to remove from album.val photoList: List<PhotoItem> = listOf()
// ...
// Returns an OperationRemovePhotos object from which information about the operation can be // obtained. For example, to know about the completion of an operation, you need to // subscribe to the single included in the operation object.disposable = PhotoManager.albums.operations        .removePhotos(albumId, photoList)        .single        .observeOn(AndroidSchedulers.mainThread())        .subscribeBy(                onSuccess = { // it: AlbumItem!                    // Handle it                },                onError = { // it: Throwable                    // Handle it                }        )// ...
// 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()

Links - PhotoItem, OperationRemovePhotos.