package ca.josephroque.bowlingcompanion.utilities;
import android.app.AlertDialog;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.preference.PreferenceManager;
import android.view.View;
import ca.josephroque.bowlingcompanion.Constants;
import ca.josephroque.bowlingcompanion.R;
/**
* Created by Joseph Roque on 15-03-03. Provides methods for determining the level of user interaction with the
* application, and offering a prompt to rate the app if they desire, or disable the prompt if not.
*/
public final class AppRater {
/** Identifies output from this class in Logcat. */
@SuppressWarnings("unused")
private static final String TAG = "AppRater";
/** Package the app has been created in. */
private static final String APP_PACKAGE_NAME = "ca.josephroque.bowlingcompanion";
/** Minimum number of days to wait before displaying prompt. */
private static final int DAYS_UNTIL_PROMPT = 14;
/** Minimum number of launches to wait before displaying prompt. */
private static final int LAUNCHES_UNTIL_PROMPT = 3;
/** Minimum number of days to wait between showings of the rate prompt. */
private static final int DAYS_BETWEEN_PROMPTS = 14;
/** Identifier for number of times app has been launched, stored in preferences. */
private static final String PREF_LAUNCH_COUNT = "lc";
/** Identifier for indicating whether the prompt should be shown or not. */
private static final String PREF_DO_NOT_SHOW = "ds";
/** Identifier for date of first launch, stored in preferences. */
private static final String PREF_FIRST_LAUNCH = "fl";
/** Identifier for date of the last time the app prompted the user to rate. */
private static final String PREF_LAST_PROMPT_TIME = "apprate_last_prompt_time";
/** Amount of time the app should wait before showing the rate dialog, in milliseconds. */
private static final long MILLISECONDS_UNTIL_PROMPT = DAYS_UNTIL_PROMPT * 24 * 60 * 60 * 1000;
/** Amount of time the app should wait between showing the rate dialog, in milliseconds. */
private static final long MILLISECONDS_BETWEEN_PROMPTS = DAYS_BETWEEN_PROMPTS * 24 * 60 * 60 * 1000;
/**
* Checks whether conditions to display the prompt have been met and, if so, displays it.
*
* @param context context to contain the prompt
*/
public static void appLaunched(Context context) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
if (preferences.getBoolean(PREF_DO_NOT_SHOW, false))
return;
SharedPreferences.Editor editor = preferences.edit();
// Gets number of launches and updates the count
long launchCount = preferences.getLong(PREF_LAUNCH_COUNT, 0) + 1;
editor.putLong(PREF_LAUNCH_COUNT, launchCount);
// Gets the date of the first launch and updates it if not set
Long dateOfFirstLaunch = preferences.getLong(PREF_FIRST_LAUNCH, 0);
if (dateOfFirstLaunch == 0) {
dateOfFirstLaunch = System.currentTimeMillis();
editor.putLong(PREF_FIRST_LAUNCH, dateOfFirstLaunch);
}
// Gets the date to wait for, in milliseconds
long dateToWaitFor = dateOfFirstLaunch + MILLISECONDS_UNTIL_PROMPT;
// Checks if the user has been prompted before and updates the next time to prompt accordingly
Long lastPromptTime = preferences.getLong(PREF_LAST_PROMPT_TIME, 0);
if (lastPromptTime != 0) {
dateToWaitFor = lastPromptTime + MILLISECONDS_BETWEEN_PROMPTS;
}
// If the conditions have been met, display the prompt
if (launchCount >= LAUNCHES_UNTIL_PROMPT
&& System.currentTimeMillis() >= dateToWaitFor) {
showRateDialog(context, editor);
editor.putLong(PREF_LAST_PROMPT_TIME, System.currentTimeMillis());
}
editor.apply();
}
/**
* Displays a prompt to the user to open the app store / browser to rate the app.
*
* @param context context to contain the prompt
* @param editor preference editor to update preferences
*/
private static void showRateDialog(final Context context, final SharedPreferences.Editor editor) {
final AlertDialog.Builder dialog = new AlertDialog.Builder(context);
View rootView = View.inflate(context, R.layout.dialog_rate, null);
dialog.setView(rootView);
final AlertDialog alertDialog = dialog.create();
View.OnClickListener listener = new View.OnClickListener() {
@Override
public void onClick(View v) {
alertDialog.dismiss();
switch (v.getId()) {
case R.id.btn_rate:
try {
context.startActivity(new Intent(Intent.ACTION_VIEW,
Uri.parse("market://details?id=" + APP_PACKAGE_NAME)));
} catch (android.content.ActivityNotFoundException ex) {
context.startActivity(new Intent(Intent.ACTION_VIEW,
Uri.parse("http://play.google.com/store/apps/details?id=" + APP_PACKAGE_NAME)));
}
disableAutomaticPrompt(editor);
break;
case R.id.btn_rate_no:
disableAutomaticPrompt(editor);
break;
case R.id.btn_rate_remind_me:
break;
default:
// do nothing
}
}
};
rootView.findViewById(R.id.btn_rate).setOnClickListener(listener);
rootView.findViewById(R.id.btn_rate_no).setOnClickListener(listener);
rootView.findViewById(R.id.btn_rate_remind_me).setOnClickListener(listener);
alertDialog.show();
}
/**
* Disables the prompt from appearing again.
*
* @param editor preference editor to update preferences
*/
private static void disableAutomaticPrompt(final SharedPreferences.Editor editor) {
editor.putBoolean(PREF_DO_NOT_SHOW, true)
.apply();
}
/**
* Default private constructor.
*/
private AppRater() {
// does nothing
}
}