How to Implement a Smart In-App Review System in Android | by Andy Jadeja | Apr, 2025

2. Create object ReviewManager Class

and copy paste this:

package com.example.utils

import android.app.Activity
import android.content.Context
import android.content.SharedPreferences
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.lifecycleScope
import com.google.android.play.core.review.ReviewManagerFactory
import kotlinx.coroutines.launch
import kotlinx.coroutines.tasks.await

object ReviewManager {

private const val PREFS_NAME = “review_prefs”
private const val KEY_APP_OPEN_COUNT = “app_open_count”
private const val KEY_DAYS_USED_SET = “days_used_set”
private const val KEY_LAST_REVIEWED = “last_reviewed”

private const val MIN_APP_OPEN_BEFORE_REVIEW = 5
private const val MIN_DIFFERENT_DAYS_USED = 3
private const val MIN_DAYS_BETWEEN_REVIEWS = 7 // days

private lateinit var prefs: SharedPreferences

fun init(context: Context) {
prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)
}

fun incrementAppOpen(context: Context) {
val today = getTodayDate()
val daysUsed = prefs.getStringSet(KEY_DAYS_USED_SET, mutableSetOf()) ?: mutableSetOf()

daysUsed.add(today)
prefs.edit()
.putStringSet(KEY_DAYS_USED_SET, daysUsed)
.putInt(KEY_APP_OPEN_COUNT, prefs.getInt(KEY_APP_OPEN_COUNT, 0) + 1)
.apply()
}

fun maybeAskForReview(activity: Activity, lifecycleOwner: LifecycleOwner) {
val appOpenCount = prefs.getInt(KEY_APP_OPEN_COUNT, 0)
val daysUsed = prefs.getStringSet(KEY_DAYS_USED_SET, mutableSetOf())?.size ?: 0
val lastReviewed = prefs.getLong(KEY_LAST_REVIEWED, 0L)

val now = System.currentTimeMillis()
val daysSinceLastReview = (now — lastReviewed) / (1000 * 60 * 60 * 24)

if (appOpenCount >= MIN_APP_OPEN_BEFORE_REVIEW &&
daysUsed >= MIN_DIFFERENT_DAYS_USED &&
daysSinceLastReview >= MIN_DAYS_BETWEEN_REVIEWS) {
requestReview(activity, lifecycleOwner)
}
}

private fun requestReview(activity: Activity, lifecycleOwner: LifecycleOwner) {
val reviewManager = ReviewManagerFactory.create(activity)

lifecycleOwner.lifecycleScope.launch {
try {
val request = reviewManager.requestReviewFlow().await()
reviewManager.launchReviewFlow(activity, request).await()

prefs.edit()
.putLong(KEY_LAST_REVIEWED, System.currentTimeMillis())
.putInt(KEY_APP_OPEN_COUNT, 0)
.putStringSet(KEY_DAYS_USED_SET, mutableSetOf())
.apply()
} catch (e: Exception) {
e.printStackTrace()
// Safe to ignore errors
}
}
}

private fun getTodayDate(): String {
val now = java.util.Calendar.getInstance()
val year = now.get(java.util.Calendar.YEAR)
val month = now.get(java.util.Calendar.MONTH) + 1 // Calendar.MONTH is 0-based
val day = now.get(java.util.Calendar.DAY_OF_MONTH)
return “$year-$month-$day”
}
}

3. Initialize in your Application class

4. Add the below code to your Main Activity to track the count
ReviewManager.incrementAppOpen(this)

5. Add this codes as well inside onResume Method

Handler(Looper.getMainLooper()).postDelayed({
ReviewManager.maybeAskForReview(this, this)
}, 2000)

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.