Skip to content

Commit 8e0c657

Browse files
authored
Merge pull request #17 from odaridavid/request-rating
show prompt for rating
2 parents 424df87 + a8d3b00 commit 8e0c657

File tree

7 files changed

+189
-3
lines changed

7 files changed

+189
-3
lines changed

.idea/icon_dark.png

29 KB
Loading

.idea/jarRepositories.xml

Lines changed: 25 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/**
2+
*
3+
* Copyright 2020 David Odari
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
6+
* in compliance with the License. You may obtain a copy of the License at
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
* Unless required by applicable law or agreed to in writing, software distributed under the License
9+
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
10+
* or implied. See the License for the specific language governing permissions and limitations under
11+
* the License.
12+
*
13+
**/
14+
package com.github.odaridavid.designpatterns
15+
16+
import android.content.SharedPreferences
17+
18+
internal interface IRatingManager {
19+
fun hasGivenRating(): Boolean
20+
fun shouldPromptForRating(): Boolean
21+
fun updatePromptForRatingCounter()
22+
fun giveRating()
23+
}
24+
25+
internal class RatingManager(private val sharedPreferences: SharedPreferences) :
26+
IRatingManager {
27+
28+
override fun hasGivenRating(): Boolean = sharedPreferences.getBoolean(RATING_PREF_KEY, false)
29+
30+
override fun giveRating() {
31+
with(sharedPreferences.edit()) {
32+
putBoolean(RATING_PREF_KEY, true)
33+
apply()
34+
}
35+
}
36+
37+
override fun shouldPromptForRating(): Boolean {
38+
val counter = sharedPreferences.getInt(PROMPT_COUNTER_PREF_KEY, 0)
39+
return counter % 5 == 0
40+
}
41+
42+
override fun updatePromptForRatingCounter() {
43+
val counter = sharedPreferences.getInt(PROMPT_COUNTER_PREF_KEY, 0) + 1
44+
with(sharedPreferences.edit()) {
45+
putInt(PROMPT_COUNTER_PREF_KEY, counter)
46+
apply()
47+
}
48+
}
49+
50+
companion object {
51+
private const val RATING_PREF_KEY = "rating"
52+
private const val PROMPT_COUNTER_PREF_KEY = "rating_prompt"
53+
}
54+
}

app/src/main/java/com/github/odaridavid/designpatterns/base/BaseActivity.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.github.odaridavid.designpatterns.base
22

33
import android.content.Context
4+
import android.content.SharedPreferences
45
import android.content.res.Configuration
56
import android.os.Build
67
import android.os.PowerManager
@@ -9,6 +10,7 @@ import androidx.annotation.RequiresApi
910
import androidx.appcompat.app.AppCompatActivity
1011
import androidx.preference.PreferenceManager
1112
import com.github.odaridavid.designpatterns.R
13+
import com.github.odaridavid.designpatterns.helpers.InjectorUtils
1214
import com.github.odaridavid.designpatterns.helpers.SdkUtils.versionFrom
1315
import com.github.odaridavid.designpatterns.helpers.SdkUtils.versionUntil
1416
import com.github.odaridavid.designpatterns.helpers.ThemeUtils
@@ -19,6 +21,10 @@ internal abstract class BaseActivity : AppCompatActivity(), ISystemThemeChangeLi
1921
getSystemService(Context.POWER_SERVICE) as PowerManager
2022
}
2123

24+
protected val sharedPref: SharedPreferences by lazy {
25+
InjectorUtils.provideSharedPreferences(this)
26+
}
27+
2228
override fun onResume() {
2329
if (versionFrom(Build.VERSION_CODES.M))
2430
matchSystemBarsWithBackground()
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/**
2+
*
3+
* Copyright 2020 David Odari
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
6+
* in compliance with the License. You may obtain a copy of the License at
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
* Unless required by applicable law or agreed to in writing, software distributed under the License
9+
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
10+
* or implied. See the License for the specific language governing permissions and limitations under
11+
* the License.
12+
*
13+
**/
14+
package com.github.odaridavid.designpatterns.helpers
15+
16+
import android.content.Context
17+
import android.content.SharedPreferences
18+
19+
20+
internal object InjectorUtils {
21+
private const val DESIGN_PATTERNS_SP_NAME = "design_patterns_pref"
22+
fun provideSharedPreferences(context: Context): SharedPreferences {
23+
return context.getSharedPreferences(DESIGN_PATTERNS_SP_NAME, Context.MODE_PRIVATE)
24+
}
25+
26+
}

app/src/main/java/com/github/odaridavid/designpatterns/ui/MainActivity.kt

Lines changed: 69 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
11
package com.github.odaridavid.designpatterns.ui
22

33
import android.app.Activity
4+
import android.content.ComponentName
45
import android.content.Intent
6+
import android.net.Uri
57
import android.os.Bundle
68
import android.view.Menu
79
import android.view.MenuItem
10+
import androidx.annotation.ColorRes
11+
import androidx.appcompat.app.AlertDialog
12+
import androidx.core.content.ContextCompat
813
import com.github.odaridavid.designpatterns.InAppUpdateManager
914
import com.github.odaridavid.designpatterns.R
15+
import com.github.odaridavid.designpatterns.RatingManager
1016
import com.github.odaridavid.designpatterns.base.BaseActivity
1117
import com.github.odaridavid.designpatterns.databinding.ActivityMainBinding
1218
import com.github.odaridavid.designpatterns.helpers.NavigationUtils
@@ -28,14 +34,74 @@ internal class MainActivity : BaseActivity() {
2834
setupDesignPatternsAdapter()
2935

3036
InAppUpdateManager(baseContext, this).checkForUpdate()
37+
38+
with(RatingManager(sharedPref)) {
39+
if (!hasGivenRating()) {
40+
updatePromptForRatingCounter()
41+
if (shouldPromptForRating()) {
42+
showRatingAlertDialog(this)
43+
}
44+
}
45+
}
46+
}
47+
48+
private fun showRatingAlertDialog(ratingManager: RatingManager) {
49+
val dialog = AlertDialog.Builder(this)
50+
.setTitle(getString(R.string.title_rating_dialog))
51+
.setMessage(getString(R.string.info_rating_message))
52+
.setNegativeButton(getString(R.string.label_dialog_negative_button), null)
53+
.setPositiveButton(getString(R.string.label_dialog_positive_button)) { dialog, _ ->
54+
ratingManager.giveRating()
55+
navigateToGooglePlayStore()
56+
}
57+
.setCancelable(true)
58+
.create()
59+
dialog.show()
60+
dialog.apply {
61+
fun loadColor(@ColorRes colorRes: Int): Int {
62+
return ContextCompat.getColor(this@MainActivity, colorRes)
63+
}
64+
getButton(AlertDialog.BUTTON_POSITIVE).setTextColor(loadColor(R.color.colorText))
65+
getButton(AlertDialog.BUTTON_NEGATIVE).setTextColor(loadColor(R.color.colorText))
66+
}
67+
}
68+
69+
private fun navigateToGooglePlayStore() {
70+
var gplayAvailable = false
71+
val appUri = Uri.parse("market://details?id=$packageName")
72+
val rateIntent = Intent(Intent.ACTION_VIEW, appUri)
73+
val gplayAppInfo = packageManager.queryIntentActivities(rateIntent, 0)
74+
.filter { it.activityInfo.applicationInfo.packageName == "com.android.vending" }
75+
if (gplayAppInfo.isNotEmpty()) {
76+
val gplayActivityInfo = gplayAppInfo.first().activityInfo
77+
val gplayComponent = ComponentName(
78+
gplayActivityInfo.applicationInfo.packageName,
79+
gplayActivityInfo.name
80+
)
81+
with(rateIntent) {
82+
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
83+
addFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED)
84+
addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
85+
setComponent(gplayComponent)
86+
}
87+
gplayAvailable = true
88+
startActivity(rateIntent)
89+
}
90+
if (!gplayAvailable) {
91+
val webIntent = Intent(
92+
Intent.ACTION_VIEW,
93+
Uri.parse("https://play.google.com/store/apps/details?id=$packageName")
94+
)
95+
startActivity(webIntent)
96+
}
3197
}
3298

3399
private fun setupDesignPatternsAdapter() {
34100
val designPatternsAdapter = DesignPatternsAdapter { designPattern ->
35-
navigateTo<DesignPatternDetailActivity>() { intent ->
36-
intent.putExtra(NavigationUtils.KEY_DESIGN_PATTERN, designPattern)
37-
}
101+
navigateTo<DesignPatternDetailActivity>() { intent ->
102+
intent.putExtra(NavigationUtils.KEY_DESIGN_PATTERN, designPattern)
38103
}
104+
}
39105
val designPatterns = generateDesignPatterns()
40106
binding.designPatternsRecyclerView.addItemDecoration(GridSpaceItemDecoration(16))
41107
binding.designPatternsRecyclerView.adapter =

app/src/main/res/values/strings.xml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,5 +172,14 @@
172172
the time of day.
173173
</string>
174174

175+
<!--Rating-->
176+
<string name="info_rating_message">
177+
If you found the app helpful or see aspects that could be improved on,feel free to leave us
178+
some feedback on playstore and rate the app.
179+
</string>
180+
<string name="title_rating_dialog">App Rating</string>
181+
<string name="label_dialog_negative_button">Later</string>
182+
<string name="label_dialog_positive_button">Rate</string>
183+
175184

176185
</resources>

0 commit comments

Comments
 (0)