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.

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

Listing 22.5  Saving the latest photo ID (PreferencesRepository.kt)

class PreferencesRepository private constructor(
    private val dataStore: DataStore<Preferences>
) {
    ...
    suspend fun setStoredQuery(query: String) {
        dataStore.edit {
            it[SEARCH_QUERY_KEY] = query
        }
    }

    val lastResultId: Flow<String> = dataStore.data.map {
        it[PREF_LAST_RESULT_ID] ?: ""
    }.distinctUntilChanged()

    suspend fun setLastResultId(lastResultId: String) {
        dataStore.edit {
            it[PREF_LAST_RESULT_ID] = lastResultId
        }
    }

    companion object {
        private val SEARCH_QUERY_KEY = stringPreferencesKey("search_query")
        private val PREF_LAST_RESULT_ID = stringPreferencesKey("lastResultId")
        private var INSTANCE: PreferencesRepository? = null
        ...
    }
}

With your preferences set up, you can start the work in PollWorker. You will need access to both PreferencesRepository and PhotoRepository to perform your work. You can get a single value out of each of the Flow properties on PreferencesRepository by calling the first() function on them. If the user has not searched for anything yet, you do not have a search term to look for new content. In that case, you can finish your work early.

Listing 22.6  Starting your work (PollWorker.kt)

class PollWorker(
    private val context: Context,
    workerParameters: WorkerParameters
) : CoroutineWorker(context, workerParameters) {
    override suspend fun doWork(): Result {
        Log.i(TAG, "Work request triggered")
        val preferencesRepository = PreferencesRepository.get()
        val photoRepository = PhotoRepository()

        val query = preferencesRepository.storedQuery.first()
        val lastId = preferencesRepository.lastResultId.first()

        if (query.isEmpty()) {
            Log.i(TAG, "No saved query, finishing early.")
            return Result.success()
        }

        return Result.success()
    }
}

When your user does have a stored query, you want to try to make a request to get the gallery items for that query. If the network request fails for any reason, have the PollWorker return Result.failure(). It is OK to fail sometimes. There are many reasons the network request could fail, and in most situations, there is nothing you can do to fix it.

If the network request does succeed, then you want to 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. Whether or not the photo IDs match, you will return Result.success().

Listing 22.7  Getting the work done (PollWorker.kt)

class PollWorker(
    private val context: Context,
    workerParameters: WorkerParameters
) : CoroutineWorker(context, workerParameters) {
    override suspend fun doWork(): Result {
        val preferencesRepository = PreferencesRepository.get()
        val photoRepository = PhotoRepository()

        val query = preferencesRepository.storedQuery.first()
        val lastId = preferencesRepository.lastResultId.first()

        if (query.isEmpty()) {
            Log.i(TAG, "No saved query, finishing early.")
            return Result.success()
        }

        return Result.success()
        return try {
            val items = photoRepository.searchPhotos(query)

            if (items.isNotEmpty()) {
                val newResultId = items.first().id
                if (newResultId == lastId) {
                    Log.i(TAG, "Still have the same result: $newResultId")
                } else {
                    Log.i(TAG, "Got a new result: $newResultId")
                    preferencesRepository.setLastResultId(newResultId)
                }
            }

            Result.success()
        } catch (ex: Exception) {
            Log.e(TAG, "Background update failed", ex)
            Result.failure()
        }
    }
}

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 that PollWorker found a new result. If you quickly run the app again, you should see that your worker finds the same ID.

    20:08:05.930 I/PollWorker: Got a new result: 51873395252
    20:08:05.987 I/WM-WorkerWrapper: Worker result SUCCESS for Work [ id=988...
    20:08:35.189 I/PollWorker: Still have the same result: 51873395252
    20:08:35.192 I/WM-WorkerWrapper: Worker result SUCCESS for Work [ id=88b...
..................Content has been hidden....................

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