Checking for New Photos

Now that your worker is executing, you can add the logic to check for new photos. There are a couple pieces needed for this functionality. You will first need a way to save the ID of the most recent photo the user has seen, then you will need to update your worker class to pull the new photos and compare the stored ID with the newest one from the server. Your worker will also handle picking the request type if there is an existing search query.

The first change you will make is to update QueryPreferences to store and retrieve the latest photo ID from shared preferences.

Listing 27.5  Saving the latest photo ID (QueryPreference.kt)

private const val PREF_SEARCH_QUERY = "searchQuery"
private const val PREF_LAST_RESULT_ID = "lastResultId"

object QueryPreferences {
    ...
    fun setStoredQuery(context: Context, query: String) {
        ...
    }

    fun getLastResultId(context: Context): String {
        return PreferenceManager.getDefaultSharedPreferences(context)
            .getString(PREF_LAST_RESULT_ID, "")!!
    }

    fun setLastResultId(context: Context, lastResultId: String) {
        PreferenceManager.getDefaultSharedPreferences(context).edit {
            putString(PREF_LAST_RESULT_ID, lastResultId)
        }
    }
}

As you did in Chapter 26, you use the non-null assertion operator (!!) when retrieving the last result ID from the default SharedPreferences instance in getLastResultId(…) because the String returned from getString(PREF_LAST_RESULT_ID, "") should never be null.

With the ability to store photo IDs in place, you can move on to polling for new photos. You will need to update FlickrFetchr to allow your PollWorker to perform synchronous web requests. Both the fetchPhotos() and searchPhotos() functions perform the requests asynchronously and deliver the results using LiveData. Since your PollWorker executes on a background thread, you do not need FlickrFetchr to do the request for you. Update FlickrFetchr to expose the Retrofit Call objects for your worker to use.

Listing 27.6  Exposing Call objects (FlickrFetchr.kt)

class FlickrFetchr {
    ...
    fun fetchPhotosRequest(): Call<FlickrResponse> {
        return flickrApi.fetchPhotos()
    }

    fun fetchPhotos(): LiveData<List<GalleryItem>> {
        return fetchPhotoMetadata(flickrApi.fetchPhotos())
        return fetchPhotoMetadata(fetchPhotosRequest())
    }

    fun searchPhotosRequest(query: String): Call<FlickrResponse> {
        return flickrApi.searchPhotos(query)
    }

    fun searchPhotos(query: String): LiveData<List<GalleryItem>> {
        return fetchPhotoMetadata(flickrApi.searchPhotos(query))
        return fetchPhotoMetadata(searchPhotosRequest(query))
    }
    ...
}

With the Call objects exposed in FlickrFetchr, you can add the queries to PollWorker. You will need to determine which request PollWorker should make based on whether there is a saved search query. Once you fetch the most up-to-date photos, you will check whether the most recent photo ID matches the one you have saved. If they do not match, then you will show the user a notification.

Start by pulling out the current search query and latest photo ID from QueryPreferences. If there is no search query, fetch the regular photos. If there is a search query, perform the search request. For safety, use an empty list if either request fails to return any photos. Delete the log statement while you are at it, since it is no longer needed.

Listing 27.7  Fetching recent photos (PollWorker.kt)

class PollWorker(val context: Context, workerParameters: WorkerParameters)
    : Worker(context, workerParameters) {

    override fun doWork(): Result {
        Log.i(TAG, "Work request triggered")
        val query = QueryPreferences.getStoredQuery(context)
        val lastResultId = QueryPreferences.getLastResultId(context)
        val items: List<GalleryItem> = if (query.isEmpty()) {
            FlickrFetchr().fetchPhotosRequest()
                .execute()
                .body()
                ?.photos
                ?.galleryItems
        } else {
            FlickrFetchr().searchPhotosRequest(query)
                .execute()
                .body()
                ?.photos
                ?.galleryItems
        } ?: emptyList()
        return Result.success()
    }
}

Next, return from the doWork() function if the items list is empty. Otherwise, check to see whether there are new photos by comparing the ID of the first item in the list with the lastResultId property. Add log statements so you can see the output of your worker. Also, update the last result ID in QueryPreferences if you found a new result.

Listing 27.8  Checking for new photos (PollWorker.kt)

class PollWorker(val context: Context, workerParameters: WorkerParameters)
    : Worker(context, workerParameters) {

    override fun doWork(): Result {
        val query = QueryPreferences.getStoredQuery(context)
        val lastResultId = QueryPreferences.getLastResultId(context)
        val items: List<GalleryItem> = if (query.isEmpty()) {
            ...
        } else {
            ...
        }

        if (items.isEmpty()) {
            return Result.success()
        }

        val resultId = items.first().id
        if (resultId == lastResultId) {
            Log.i(TAG, "Got an old result: $resultId")
        } else {
            Log.i(TAG, "Got a new result: $resultId")
            QueryPreferences.setLastResultId(context, resultId)
        }

        return Result.success()
    }
}

Run your app on a device or emulator. The first time you run it, there will not be a last result ID saved in QueryPreferences, so you should see the log statement indicating PollWorker found a new result. If you quickly run the app again, you should see that your worker finds the same ID (Figure 27.3). (Make sure your Logcat is set to No Filters, as shown, and not Show only selected application.)

Figure 27.3  Finding new and old results

Finding new and old results
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.83.87.94