Как реализовать функцию Rate It в Android-приложении


Я разрабатываю приложение для Android. В которой все работает правильно. Мое приложение готово к запуску. Но там мне нужно реализовать еще одну функцию. Мне нужно отобразить всплывающее окно, которое содержит

Rate It и Remind me later

здесь, если какой-либо пользователь оценить приложение на рынке, то всплывающее окно не исчезнет. Я искал в Google и нашел одну ссылку. С этим я понимаю, что его невозможно узнать. Так что мне нужно предложение для этого.

есть кто-нибудь сталкивались с такой ситуацией раньше? Если да, то есть ли какое-либо решение или Альтернатива для этого?

9 65

9 ответов:

я реализовал это некоторое время назад, в какой-то степени. Невозможно узнать, оценил ли пользователь приложение, чтобы рейтинги не стали валютой (некоторые разработчики могут добавить такую опцию, как "оценить это приложение и получить так и так в приложении бесплатно").

класс, который я написал, предоставляет три кнопки и настраивает диалоговое окно так, чтобы оно отображалось только после запуска приложения n раз (пользователи имеют более высокий шанс рейтинга приложения, если они использовали его немного до. Большинство из них вряд ли даже знаете, что он делает при первом запуске):

public class AppRater {
    private final static String APP_TITLE = "App Name";// App Name
    private final static String APP_PNAME = "com.example.name";// Package Name

    private final static int DAYS_UNTIL_PROMPT = 3;//Min number of days
    private final static int LAUNCHES_UNTIL_PROMPT = 3;//Min number of launches

    public static void app_launched(Context mContext) {
        SharedPreferences prefs = mContext.getSharedPreferences("apprater", 0);
        if (prefs.getBoolean("dontshowagain", false)) { return ; }

        SharedPreferences.Editor editor = prefs.edit();

        // Increment launch counter
        long launch_count = prefs.getLong("launch_count", 0) + 1;
        editor.putLong("launch_count", launch_count);

        // Get date of first launch
        Long date_firstLaunch = prefs.getLong("date_firstlaunch", 0);
        if (date_firstLaunch == 0) {
            date_firstLaunch = System.currentTimeMillis();
            editor.putLong("date_firstlaunch", date_firstLaunch);
        }

        // Wait at least n days before opening
        if (launch_count >= LAUNCHES_UNTIL_PROMPT) {
            if (System.currentTimeMillis() >= date_firstLaunch + 
                    (DAYS_UNTIL_PROMPT * 24 * 60 * 60 * 1000)) {
                showRateDialog(mContext, editor);
            }
        }

        editor.commit();
    }   

    public static void showRateDialog(final Context mContext, final SharedPreferences.Editor editor) {
        final Dialog dialog = new Dialog(mContext);
        dialog.setTitle("Rate " + APP_TITLE);

        LinearLayout ll = new LinearLayout(mContext);
        ll.setOrientation(LinearLayout.VERTICAL);

        TextView tv = new TextView(mContext);
        tv.setText("If you enjoy using " + APP_TITLE + ", please take a moment to rate it. Thanks for your support!");
        tv.setWidth(240);
        tv.setPadding(4, 0, 4, 10);
        ll.addView(tv);

        Button b1 = new Button(mContext);
        b1.setText("Rate " + APP_TITLE);
        b1.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                mContext.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + APP_PNAME)));
                dialog.dismiss();
            }
        });        
        ll.addView(b1);

        Button b2 = new Button(mContext);
        b2.setText("Remind me later");
        b2.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                dialog.dismiss();
            }
        });
        ll.addView(b2);

        Button b3 = new Button(mContext);
        b3.setText("No, thanks");
        b3.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                if (editor != null) {
                    editor.putBoolean("dontshowagain", true);
                    editor.commit();
                }
                dialog.dismiss();
            }
        });
        ll.addView(b3);

        dialog.setContentView(ll);        
        dialog.show();        
    }
}

интеграция класса так же просто, как добавление:

AppRater.app_launched(this);

В вашей деятельности. Он должен быть добавлен только к одному виду деятельности во всем приложении.

Я использую этот:https://github.com/kskkbys/Android-RateThisApp -- приятное, ненавязчивое поведение. RateThisApp screenshot from kskkbys

мой один с помощью DialogFragment:

public class RateItDialogFragment extends DialogFragment {
    private static final int LAUNCHES_UNTIL_PROMPT = 10;
    private static final int DAYS_UNTIL_PROMPT = 3;
    private static final int MILLIS_UNTIL_PROMPT = DAYS_UNTIL_PROMPT * 24 * 60 * 60 * 1000;
    private static final String PREF_NAME = "APP_RATER";
    private static final String LAST_PROMPT = "LAST_PROMPT";
    private static final String LAUNCHES = "LAUNCHES";
    private static final String DISABLED = "DISABLED";

    public static void show(Context context, FragmentManager fragmentManager) {
        boolean shouldShow = false;
        SharedPreferences sharedPreferences = getSharedPreferences(context);
        SharedPreferences.Editor editor = sharedPreferences.edit();
        long currentTime = System.currentTimeMillis();
        long lastPromptTime = sharedPreferences.getLong(LAST_PROMPT, 0);
        if (lastPromptTime == 0) {
            lastPromptTime = currentTime;
            editor.putLong(LAST_PROMPT, lastPromptTime);
        }

        if (!sharedPreferences.getBoolean(DISABLED, false)) {
            int launches = sharedPreferences.getInt(LAUNCHES, 0) + 1;
            if (launches > LAUNCHES_UNTIL_PROMPT) {
                if (currentTime > lastPromptTime + MILLIS_UNTIL_PROMPT) {
                    shouldShow = true;
                }
            }
            editor.putInt(LAUNCHES, launches);
        }

        if (shouldShow) {
            editor.putInt(LAUNCHES, 0).putLong(LAST_PROMPT, System.currentTimeMillis()).commit();
            new RateItDialogFragment().show(fragmentManager, null);
        } else {
            editor.commit();
        }
    }

    private static SharedPreferences getSharedPreferences(Context context) {
        return context.getSharedPreferences(PREF_NAME, 0);
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        return new AlertDialog.Builder(getActivity())
                .setTitle(R.string.rate_title)
                .setMessage(R.string.rate_message)
                .setPositiveButton(R.string.rate_positive, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + getActivity().getPackageName())));
                        getSharedPreferences(getActivity()).edit().putBoolean(DISABLED, true).commit();
                        dismiss();
                    }
                })
                .setNeutralButton(R.string.rate_remind_later, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dismiss();
                    }
                })
                .setNegativeButton(R.string.rate_never, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        getSharedPreferences(getActivity()).edit().putBoolean(DISABLED, true).commit();
                        dismiss();
                    }
                }).create();
    }
}

тогда используйте его в onCreate() основной FragmentActivity:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ...

    RateItDialogFragment.show(this, getFragmentManager());

}

Я думаю, что то, что вы пытаетесь сделать, вероятно, контрпродуктивно.

Что делает его легким для людей, чтобы оценить приложения, как правило, хорошая идея, как и большинство людей, которые беспокоятся сделать это, потому что им нравится приложение. Ходят слухи, что количество рейтингов влияет на ваш рыночный рейтинг (хотя я вижу мало доказательств этого). Доставать пользователей в клиентов - через экраны кляча - это, скорее всего, чтобы вызвать людей, чтобы очистить пилить через отъездом плохой рейтинг.

добавление возможности прямая оценка приложения вызвала небольшое снижение числовых рейтингов для моей бесплатной версии и небольшое увеличение моего платного приложения. Для бесплатного приложения мои 4-звездочные рейтинги увеличились больше, чем мои 5-звездочные рейтинги, так как люди, которые думали, что мое приложение было хорошим, но не отличным, начали оценивать его. Изменение было около -0.2. Для платных, изменение было около + 0.1. Я должен удалить его из бесплатной версии, за исключением того, что мне нравится получать много комментариев.

Я поместил свою кнопку рейтинга в настройки (предпочтение) экран, где это не влияет на нормальную работу. Это все еще увеличило мой рейтинг в 4 или 5 раз. Я не сомневаюсь, что если бы я попытался заставить своих пользователей сделать рейтинг, я бы получил много пользователей, дающих мне плохие оценки в знак протеста.

использовать эту библиотеку, это просто и легко.. https://github.com/hotchemi/Android-Rate

путем добавления зависимостей..

dependencies {
  compile 'com.github.hotchemi:android-rate:0.5.6'
}

Я использую это простое решение. Вы можете просто добавить эту библиотеку с Gradle: https://github.com/fernandodev/easy-rating-dialog

compile 'com.github.fernandodev.easyratingdialog:easyratingdialog:+'

это решение очень похоже на представленные выше. Единственная разница заключается в том, что вы сможете задержать приглашение диалогового окна рейтинга на запуски и дни. Если кнопка напомнить мне позже нажата, то я задержу всплывающее окно на 3 дня и 10 запусков. То же самое делается для тех, кто выбрал, чтобы оценить его, однако задержки больше (не беспокоить пользователя так скоро, если он на самом деле оценил приложение. Это может быть изменено, чтобы не отображаться снова, то вы будете придется изменить код на свой подобный). Надеюсь, это кому-то поможет!

public class AppRater {
    private final static String APP_TITLE = "your_app_name";
    private static String PACKAGE_NAME = "your_package_name";
    private static int DAYS_UNTIL_PROMPT = 5;
    private static int LAUNCHES_UNTIL_PROMPT = 10;
    private static long EXTRA_DAYS;
    private static long EXTRA_LAUCHES;
    private static SharedPreferences prefs;
    private static SharedPreferences.Editor editor;
    private static Activity activity;

    public static void app_launched(Activity activity1) {
        activity = activity1;

        Configs.sendScreenView("Avaliando App", activity);

        PACKAGE_NAME = activity.getPackageName();

        prefs = activity.getSharedPreferences("apprater", Context.MODE_PRIVATE);
        if (prefs.getBoolean("dontshowagain", false)) 
            return;

        editor = prefs.edit();

        EXTRA_DAYS = prefs.getLong("extra_days", 0);
        EXTRA_LAUCHES = prefs.getLong("extra_launches", 0);

        // Increment launch counter
        long launch_count = prefs.getLong("launch_count", 0) + 1;
        editor.putLong("launch_count", launch_count);

        // Get date of first launch
        Long date_firstLaunch = prefs.getLong("date_firstlaunch", 0);
        if (date_firstLaunch == 0) {
            date_firstLaunch = System.currentTimeMillis();
            editor.putLong("date_firstlaunch", date_firstLaunch);
        }

        // Wait at least n days before opening
        if (launch_count >= (LAUNCHES_UNTIL_PROMPT + EXTRA_LAUCHES))
            if (System.currentTimeMillis() >= date_firstLaunch + (DAYS_UNTIL_PROMPT * 24 * 60 * 60 * 1000) + EXTRA_DAYS)
                showRateDialog();

        editor.commit();
    }   

    public static void showRateDialog() {
        final Dialog dialog = new Dialog(activity);
        dialog.setTitle("Deseja avaliar o aplicativo " + APP_TITLE + "?");

        LinearLayout ll = new LinearLayout(activity);
        ll.setOrientation(LinearLayout.VERTICAL);
        ll.setPadding(5, 5, 5, 5);

        TextView tv = new TextView(activity);
        tv.setTextColor(activity.getResources().getColor(R.color.default_text));
        tv.setText("Ajude-nos a melhorar o aplicativo com sua avaliação no Google Play!");
        tv.setWidth(240);
        tv.setGravity(Gravity.CENTER);
        tv.setPadding(5, 5, 5, 5);
        ll.addView(tv);

        Button b1 = new Button(activity);
        b1.setTextColor(activity.getResources().getColor(R.color.default_text));
        b1.setBackground(activity.getResources().getDrawable(R.drawable.rounded_blue_box));
        b1.setTextColor(Color.WHITE);
        b1.setText("Avaliar aplicativo " + APP_TITLE + "!");
        b1.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                Configs.sendHitEvents(Configs.APP_RATER, Configs.CATEGORIA_ANALYTICS, "Clique", "Avaliar", activity);

                activity.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + PACKAGE_NAME)));
                delayDays(60);
                delayLaunches(30);
                dialog.dismiss();
            }
        });        
        ll.addView(b1);
        LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) b1.getLayoutParams();
        params.setMargins(5, 3, 5, 3);
        b1.setLayoutParams(params);

        Button b2 = new Button(activity);
        b2.setTextColor(activity.getResources().getColor(R.color.default_text));
        b2.setBackground(activity.getResources().getDrawable(R.drawable.rounded_blue_box));
        b2.setTextColor(Color.WHITE);
        b2.setText("Lembre-me mais tarde!");
        b2.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                Configs.sendHitEvents(Configs.APP_RATER, Configs.CATEGORIA_ANALYTICS, "Clique", "Avaliar Mais Tarde", activity);
                delayDays(3);
                delayLaunches(10);
                dialog.dismiss();
            }
        });
        ll.addView(b2);
        params = (LinearLayout.LayoutParams) b2.getLayoutParams();
        params.setMargins(5, 3, 5, 3);
        b2.setLayoutParams(params);

        Button b3 = new Button(activity);
        b3.setTextColor(activity.getResources().getColor(R.color.default_text));
        b3.setBackground(activity.getResources().getDrawable(R.drawable.rounded_blue_box));
        b3.setTextColor(Color.WHITE);
        b3.setText("Não, obrigado!");
        b3.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                Configs.sendHitEvents(Configs.APP_RATER, Configs.CATEGORIA_ANALYTICS, "Clique", "Não Avaliar", activity);

                if (editor != null) {
                    editor.putBoolean("dontshowagain", true);
                    editor.commit();
                }
                dialog.dismiss();
            }
        });
        ll.addView(b3);
        params = (LinearLayout.LayoutParams) b3.getLayoutParams();
        params.setMargins(5, 3, 5, 0);
        b3.setLayoutParams(params);

        dialog.setContentView(ll);        
        dialog.show();        
    }

    private static void delayLaunches(int numberOfLaunches) {
        long extra_launches = prefs.getLong("extra_launches", 0) + numberOfLaunches;
        editor.putLong("extra_launches", extra_launches);
        editor.commit();
    }

    private static void delayDays(int numberOfDays) {
        Long extra_days = prefs.getLong("extra_days", 0) + (numberOfDays * 1000 * 60 * 60 * 24);
        editor.putLong("extra_days", extra_days);
        editor.commit();
    }
}

кнопки имеют определенный цвет и фон. Фон, как показано в этом xml-файле:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:padding="10dp"
    android:shape="rectangle" >

    <solid android:color="#2E78B9" />

    <corners
        android:bottomLeftRadius="6dp"
        android:bottomRightRadius="6dp"
        android:topLeftRadius="6dp"
        android:topRightRadius="6dp" />

</shape>

источник: Android подход для "оценить мое приложение"

AndroidRate это библиотека, которая поможет вам продвигать ваше приложение для android, предлагая пользователям оценить приложение после его использования в течение нескольких дней.

Модуль Gradle:

dependencies {
  implementation 'com.vorlonsoft:androidrate:1.0.8'
}

MainActivity.java:

@Override
protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);

  AppRate.with(this)
      .setStoreType(StoreType.GOOGLEPLAY) //default is GOOGLEPLAY (Google Play), other options are
                                          //           AMAZON (Amazon Appstore) and
                                          //           SAMSUNG (Samsung Galaxy Apps)
      .setInstallDays((byte) 0) // default 10, 0 means install day
      .setLaunchTimes((byte) 3) // default 10
      .setRemindInterval((byte) 2) // default 1
      .setRemindLaunchTimes((byte) 2) // default 1 (each launch)
      .setShowLaterButton(true) // default true
      .setDebug(false) // default false
      //Java 8+: .setOnClickButtonListener(which -> Log.d(MainActivity.class.getName(), Byte.toString(which)))
      .setOnClickButtonListener(new OnClickButtonListener() { // callback listener.
          @Override
          public void onClickButton(byte which) {
              Log.d(MainActivity.class.getName(), Byte.toString(which));
          }
      })
      .monitor();

  if (AppRate.with(this).getStoreType() == StoreType.GOOGLEPLAY) {
      //Check that Google Play is available
      if (GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(this) != ConnectionResult.SERVICE_MISSING) {
          // Show a dialog if meets conditions
          AppRate.showRateDialogIfMeetsConditions(this);
      }
  } else {
      // Show a dialog if meets conditions
      AppRate.showRateDialogIfMeetsConditions(this);
  }
}

условия по умолчанию для отображения диалогового окна скорости, как показано ниже:

  1. приложение запускается более чем на 10 дней позже, чем установка. Изменение через AppRate#setInstallDays(byte).
  2. приложение запускается более 10 раз. Изменение через AppRate#setLaunchTimes(byte).
  3. приложение запускается более чем через 1 день после нажатия нейтральной кнопки. Изменение через AppRate#setRemindInterval(byte).
  4. приложение запускается X раз и X % 1 = 0. Изменение через AppRate#setRemindLaunchTimes(byte).
  5. приложение показывает нейтральный диалог (напомните мне позже) по умолчанию. Изменение через setShowLaterButton(boolean).
  6. чтобы указать обратный вызов при нажатии кнопки. То же значение, что и второй аргумент DialogInterface.OnClickListener#onClick будет передано в аргументе onClickButton.
  7. задание AppRate#setDebug(boolean) будет убедитесь, что запрос рейтинга отображается каждый раз при запуске приложения. эта функция предназначена только для разработки!.

дополнительные требования к пользовательским событиям для отображения диалогового окна

вы можете добавить дополнительные дополнительные требования для отображения диалогового окна. Каждое требование может быть добавлено / указано как уникальная строка. Вы можете установить минимальное количество для каждого такого события (например, "action_performed" 3 раза, "button_clicked" 5 раз, так далее.)

AppRate.with(this).setMinimumEventCount(String, short);
AppRate.with(this).incrementEventCount(String);
AppRate.with(this).setEventCountValue(String, short);

снимите флажок Показать диалог

если вы хотите снова показать диалог, позвоните AppRate#clearAgreeShowDialog().

AppRate.with(this).clearAgreeShowDialog();

когда кнопка нажимает на

вызов AppRate#showRateDialog(Activity).

AppRate.with(this).showRateDialog(this);

установить пользовательский вид

вызов AppRate#setView(View).

LayoutInflater inflater = (LayoutInflater)this.getSystemService(LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.custom_dialog, (ViewGroup)findViewById(R.id.layout_root));
AppRate.with(this).setView(view).monitor();

специфическая тема

вы можете использовать определенную тему, чтобы раздуть диалог.

AppRate.with(this).setThemeResId(int);

настраиваемые диалоговые

если вы хотите используйте свои собственные диалоговые метки, переопределите строковые xml-ресурсы в своем приложении.

<resources>
    <string name="rate_dialog_title">Rate this app</string>
    <string name="rate_dialog_message">If you enjoy playing this app, would you mind taking a moment to rate it? It won\'t take more than a minute. Thanks for your support!</string>
    <string name="rate_dialog_ok">Rate It Now</string>
    <string name="rate_dialog_cancel">Remind Me Later</string>
    <string name="rate_dialog_no">No, Thanks</string>
</resources>

проверьте, что Google Play доступен

if (GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(this) != ConnectionResult.SERVICE_MISSING) {

}

Как вы видите из другого сообщения, которое вы связали, приложение не может узнать, оставил ли пользователь отзыв или нет. И не зря.

подумайте об этом, если приложение может сказать, оставил ли пользователь отзыв или нет, разработчик может ограничить определенные функции, которые будут разблокированы только в том случае, если пользователь оставит Рейтинг 5/5. Это приведет к тому, что другие пользователи Google Play не будут доверять отзывам и подорвут систему рейтингов.

альтернатива решения я видел, что приложение напоминает пользователю представить рейтинг всякий раз, когда приложение открывается определенное количество раз, или заданный интервал. Например, каждый 10-й раз, когда приложение открывается, попросите пользователя оставить рейтинг и предоставить кнопку "уже сделано" и "напомнить мне позже". Продолжайте показывать это сообщение, если пользователь решил напомнить ему/ей позже. Некоторые другие разработчики приложений показывают это сообщение с увеличивающимся интервалом (например, 5, 10, 15nth раз приложение открыто), потому что если пользователь не оставил отзыв, например, в 100-й раз, когда приложение было открыто, вероятно, он/она не оставит его.

Это решение не идеально, но я думаю, что это лучшее, что у вас есть на данный момент. Это приводит к тому, что Вы доверяете пользователю, но понимаете, что альтернатива будет означать потенциально худший опыт для всех на рынке приложений.