Notes: 09. Add Final Touches
If you want to access the current live version of the code for the raywenderlich.com app, known as Emitron, head over to its public repository: https://github.com/razeware/emitron-Android.
Additionally, you can contribute to the repository by looking at open issues and submitting a pull request, following the repository instructions.
If you want to check out the official documentation, head over to: https://developer.android.com/guide/playcore/in-app-review.
Now that you’ve built everything and tested your In App Review feature, it’s time to improve the experience and add some final touches. Open the InAppReviewManagerImpl.kt file and change the startReview() function like so:
override fun startReview(activity: Activity) {
if (reviewInfo != null) {
reviewManager.launchReviewFlow(activity, reviewInfo).addOnCompleteListener { reviewFlow ->
onReviewFlowLaunchCompleted(reviewFlow)
}
} else {
sendUserToPlayStore()
}
}
Here, you added an else clause, where if the reviewInfo isn’t valid, you instead proceed to send the user to the Play Store. This is not as efficient as the In App Review feature, but it’s still a good safety net. Now let’s also change the onReviewFlowLaunchCompleted() to do the same:
private fun onReviewFlowLaunchCompleted(reviewFlow: Task<Void>) {
if (reviewFlow.isSuccessful) {
logSuccess()
} else {
sendUserToPlayStore()
}
}
Just like with the startReview() function, if something goes bad, you’ll send the user to the Play Store and try to have them rate the app there.
Now build the missing sendUserToPlayStore() function like so:
private fun sendUserToPlayStore() {
val appPackageName = context.packageName
try {
context.startActivity(
Intent(
Intent.ACTION_VIEW,
Uri.parse("market://details?id=$appPackageName")
)
)
} catch (error: Error) {
context.startActivity(
Intent(
Intent.ACTION_VIEW,
Uri.parse("https://play.google.com/store/apps/details?id=$appPackageName")
)
)
}
}
This is a larger piece of code, but it’s rather simple. You fetch the appPackageName from the context, to be able to send users to the appropriate app on the Play Store. Then you try to do so within a try/catch block.
The reason for this is because sometimes, the market:// based URI doesn’t work and you might get an error. In that case, you try to open the direct link to the Play Store web page instead, which should show your app to the user. This is a good safety measure to make sure the user gets to your app one way or another. Note that this will only work if the IAR flow fails.
Now, for the second set of improvements. Add the following function to the InAppReviewPreferences interface and its implementation:
fun clearIfUserDidNotRate()
override fun clearIfUserDidNotRate() {
if (!hasUserRatedApp()) {
sharedPreferences.edit {
putBoolean(KEY_CHOSEN_RATE_LATER, false)
putLong(KEY_RATE_LATER_TIME, 0)
}
}
}
This will help you reset the rate later time, in case you add new features that the user might want to rethink their rate choice about. One great example for the Emitron app would be to add book reading features, and if the user tries them out or finishes the onboarding part of the feature, it should be fine to ask them to review even though they said they’ll rate the app later.
That’s fine because the new feature might entice them to rate the app now and in turn, get you a few extra positive ratings! :]
These few changes are really important to keep your review process and logic sharp and future-proof. I hope you’ve learned a lot during this course and I hope your apps will enjoy a high rating once you add the In App Review feature to them! Good luck!