web-dev-qa-db-fra.com

Comment implémenter Rate It dans Android App

Je développe une Android App. Dans laquelle tout fonctionne correctement. Mon application est prête à être lancée. Mais là, je dois implémenter une fonctionnalité supplémentaire. Je dois afficher une fenêtre contextuelle contenant

Rate It et Remind me later

Ici, si un utilisateur évalue l'application sur le marché, la fenêtre contextuelle ne disparaîtra pas. J'ai cherché dans Google et trouvé un lien . Avec cela, je comprends qu'il n'est pas possible de savoir. J'ai donc besoin d'une suggestion pour cela.

Quelqu'un a-t-il déjà affronté cette situation? Si oui, y a-t-il une solution ou une alternative pour cela?

86
Naveen

Je l'ai mis en œuvre il y a quelque temps, dans une certaine mesure. Il est impossible de savoir si un utilisateur a évalué une application, pour éviter que les évaluations ne deviennent une devise (certains développeurs pourraient ajouter une option du type "Évaluez cette application et obtenez-la dans l'application gratuitement").

La classe que j'ai écrite fournit trois boutons et configure la boîte de dialogue de manière à ce qu'elle ne s'affiche qu'après le lancement de l'application n fois (les utilisateurs ont plus de chances de noter l'application s'ils l'ont utilisée un peu avant Il est peu probable que la plupart d’entre eux sachent ce qu’il fait au premier passage):

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();        
    }
}

L'intégration de la classe est aussi simple que d'ajouter:

AppRater.app_launched(this);

Pour votre activité. Il ne doit être ajouté qu'à une seule activité de l'application.

162
Raghav Sood

J'utilise celui-ci: https://github.com/kskkbys/Android-RateThisApp - Beau, genre de comportement discret. RateThisApp screenshot from kskkbys

33
saschoar

Mon seul utilisant 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();
    }
}

Ensuite, utilisez-le dans onCreate() de votre FragmentActivity principal:

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

    RateItDialogFragment.show(this, getFragmentManager());

}
16
mixel

Je pense que ce que vous essayez de faire est probablement contre-productif.

Il est généralement judicieux de donner une note facile aux utilisateurs pour évaluer les applications, car la plupart des gens qui s’ennuient le font parce qu’ils aiment l’application. La rumeur dit que le nombre de notes affecte votre note de marché (bien que je ne voie que peu de preuves à ce sujet). Les utilisateurs difficiles à évaluer - à travers des écrans de rappel - sont susceptibles de forcer les gens à effacer le problème en laissant une mauvaise évaluation.

L'ajout de la possibilité d'évaluer directement une application a entraîné une légère diminution des notations numériques pour ma version gratuite et une légère augmentation de mon application payante. Pour l'application gratuite, mes notes 4 étoiles ont augmenté plus que mes notes 5 étoiles, car les personnes qui pensaient que mon application était bonne mais pas excellente ont commencé à la noter également. Le changement était d'environ -0,2. Pour les payés, le changement était d'environ +0,1. Je devrais le supprimer de la version gratuite, sauf que j'aime beaucoup de commentaires.

Je mets mon bouton de classement dans un écran de paramètres (préférences), où il n’affecte pas le fonctionnement normal. Cela a quand même augmenté mon taux d'évaluation par un facteur de 4 ou 5. Je ne doute pas que si j'essayais de harceler mes utilisateurs pour qu'ils évaluent, je ferais en sorte que beaucoup d'utilisateurs me donnent de mauvaises évaluations en guise de protestation.

6
Peter Webb

AndroidRate est une bibliothèque qui vous aide à promouvoir votre Android application en incitant les utilisateurs à évaluer l'application après l'avoir utilisée pendant quelques jours.

Grade du module:

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);
  }
}

Les conditions par défaut pour afficher la boîte de dialogue de taux sont les suivantes:

  1. L'application est lancée plus de 10 jours plus tard que l'installation. Changer via AppRate#setInstallDays(byte).
  2. L'application est lancée plus de 10 fois. Changer via AppRate#setLaunchTimes(byte).
  3. L'application est lancée plus de 1 jour après le clic du bouton neutre. Changer via AppRate#setRemindInterval(byte).
  4. L'application est lancée X fois et X% 1 = 0. Modification via AppRate#setRemindLaunchTimes(byte).
  5. L'application affiche un dialogue neutre (me le rappeler plus tard) par défaut. Changer via setShowLaterButton(boolean).
  6. Pour spécifier le rappel lorsque le bouton est enfoncé. La même valeur que le deuxième argument de DialogInterface.OnClickListener#onClick Sera passée dans l'argument de onClickButton.
  7. Le réglage de AppRate#setDebug(boolean) garantira que la demande d’évaluation est affichée à chaque lancement de l’application. Cette fonctionnalité est uniquement destinée au développement! .

Exigences personnalisées facultatives pour afficher la boîte de dialogue

Vous pouvez ajouter des exigences facultatives supplémentaires pour afficher la boîte de dialogue. Chaque exigence peut être ajoutée/référencée en tant que chaîne unique. Vous pouvez définir un nombre minimal pour chaque événement de ce type (par exemple, "action_performed" 3 fois, "bouton_cliqué" 5 fois, etc.).

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

Effacer le drapeau de dialogue

Lorsque vous souhaitez afficher à nouveau la boîte de dialogue, appelez AppRate#clearAgreeShowDialog().

AppRate.with(this).clearAgreeShowDialog();

Lorsque le bouton appuie sur

appelez AppRate#showRateDialog(Activity).

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

Définir une vue personnalisée

appelez 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();

Thème spécifique

Vous pouvez utiliser un thème spécifique pour gonfler la boîte de dialogue.

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

Dialogue personnalisé

Si vous souhaitez utiliser vos propres étiquettes de dialogue, remplacez les ressources chaîne xml de votre application.

<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>

Vérifiez que Google Play est disponible

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

}
5
Alexander Savin

Utilisez cette bibliothèque, C’est simple et facile .. https://github.com/hotchemi/Android-Rate

en ajoutant la dépendance ..

dependencies {
  compile 'com.github.hotchemi:Android-rate:0.5.6'
}
3
shaiban

J'utilise cette solution facile. Vous pouvez simplement ajouter cette bibliothèque avec gradle: https://github.com/fernandodev/easy-rating-dialog

compile 'com.github.fernandodev.easyratingdialog:easyratingdialog:+'
2
Fernando Martínez

Cette solution est très similaire à celles présentées ci-dessus. La seule différence est que vous allez pouvoir différer l'invite de la boîte de dialogue d'évaluation par lancements et par jours. Si le bouton me rappeler plus tard est enfoncé, je retarderai l'affichage de 3 jours et 10 lancements. La même chose est faite pour ceux qui ont choisi de l’évaluer, mais les délais sont plus longs (pour ne pas déranger l’utilisateur si tôt au cas où il aurait évalué l’application. Cela peut être modifié pour ne plus être affiché, vous devrez alors modifiez le code à votre goût). J'espère que ça aide quelqu'un!

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();
    }
}

Les boutons ont une couleur et un fond spécifiques. L'arrière-plan est comme indiqué dans ce fichier 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>

source: approche Android pour "noter mon application"

2

Comme vous le voyez dans l'autre message que vous avez lié, l'application ne peut pas savoir si l'utilisateur a laissé un commentaire ou non. Et pour une bonne raison.

Pensez-y, si une application pouvait dire si l'utilisateur avait laissé un avis ou non, le développeur pourrait restreindre certaines fonctionnalités qui ne seraient déverrouillées que si l'utilisateur laissait une note de 5/5. Cela conduirait les autres utilisateurs de Google Play à ne pas faire confiance aux avis et à saper le système de classement.

Les solutions alternatives que j'ai vues sont que l'application rappelle à l'utilisateur de soumettre une note chaque fois que l'application est ouverte un nombre spécifique de fois, ou un intervalle défini. Par exemple, chaque 10 fois que l'application est ouverte, demandez à l'utilisateur de laisser une note et de fournir un bouton "déjà fait" et "rappelez-moi plus tard". Continuez à afficher ce message si l'utilisateur a choisi de lui rappeler ultérieurement. D'autres développeurs d'applications affichent ce message avec un intervalle croissant (par exemple, 5, 10, 15ème ouverture de l'application), car si un utilisateur n'a pas laissé de commentaire sur, par exemple, la centième fois que l'application a été ouverte, c'est probablement il/elle n'en laissera pas un.

Cette solution n'est pas parfaite, mais je pense que c'est le meilleur que vous ayez pour le moment. Cela vous amène à faire confiance à l'utilisateur, mais réalisez que cette alternative signifierait une expérience potentiellement pire pour tout le monde sur le marché des applications.

1
Vidhur Vohra