So implementieren Sie die Rate It-Funktion in der Android App


94

Ich entwickle eine Android App. In dem alles richtig funktioniert. Meine App ist startbereit. Aber da muss ich noch eine Funktion implementieren. Ich muss ein Popup anzeigen, das enthält

Rate It und Remind me later

Wenn ein Benutzer die App auf dem Markt bewertet, wird das Popup nicht ausgeblendet. Ich habe in Google gesucht und einen Link gefunden . Damit verstehe ich, dass es nicht möglich ist zu wissen. Also brauche ich einen Vorschlag dafür.

Hat sich schon jemand dieser Situation gestellt? Wenn ja, gibt es dafür eine Lösung oder eine Alternative?


Fragen Sie also nur nach der Rate it / erinnern Sie mich später oder fragen Sie, wie Sie feststellen können, ob ein bestimmter Benutzer eine Android-App bewertet hat?
wtsang02

1
Ich habe das Popup implementiert. aber wie man weiß, ob ein Benutzer die App bewertet oder nicht
Naveen

-1 Ich sehe keinen Unterschied zwischen dieser Frage und der im Link.
wtsang02

2
@ wtsang02, Kann sein wahr sein. Aber siehe die Frage. es ist weiter gefragt Mar 15 2011. also fast 20 Monate vorbei. Ich denke, jemand hat eine Lösung oder Alternative für meine Anforderung. Das ist yi hier gepostet.
Naveen

Sie können die Bibliothek github.com/Vorlonsoft/AndroidRate ( implementation 'com.vorlonsoft:androidrate:1.0.3')
Alexander Savin

Antworten:


179

Ich habe dies vor einiger Zeit bis zu einem gewissen Grad umgesetzt. Es ist unmöglich zu wissen, ob ein Benutzer eine App bewertet hat oder nicht, um zu verhindern, dass Bewertungen zu einer Währung werden (einige Entwickler fügen möglicherweise eine Option wie "Bewerten Sie diese App und erhalten Sie sie kostenlos in der App") hinzu.

Die von mir geschriebene Klasse bietet drei Schaltflächen und konfiguriert den Dialog so, dass er erst nach dem Start der App angezeigt wird n(Benutzer haben eine höhere Wahrscheinlichkeit, die App zu bewerten, wenn sie sie zuvor etwas verwendet haben. Die meisten davon sind unwahrscheinlich um überhaupt zu wissen, was es beim ersten Durchlauf macht):

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

Das Integrieren der Klasse ist so einfach wie das Hinzufügen von:

AppRater.app_launched(this);

Zu Ihrer Aktivität. Es muss nur zu einer Aktivität in der gesamten App hinzugefügt werden.


1
Dies unterstützt nicht mehrere Benutzer, die dasselbe Gerät verwenden.
AsafK

1
@AsafK Ja, aber mehrere Benutzer, die dasselbe Gerät verwenden, können behandelt werden, indem der appraterDialog erst nach der Authentifizierung angezeigt und geändert wird, shared preferenceum die Google-E-Mail-Adresse in die einzuschließen key.
Stephen

1
Hallo, ich habe nur eine Frage. Warum hast du alles statisch gemacht? Danke Raghav!
Ruchir Baronia

2
Hallo, ich versuche Ihren obigen Code. Ich habe AppRater.app_launched(this);in meine onCreate()MainActivity gesteckt. Ich habe auch die Mindestanzahl der erforderlichen Starts auf 2 geändert. Der Dialog wird jedoch nach dem Start von 2 Apps nicht angezeigt. Kannst du mir helfen? Vielen Dank!
Ausnahme

1
Verwenden Sie besser die Aufzählung Context.MODE_PRIVATE-context.getSharedPreferences("apprater", Context.MODE_PRIVATE);
Vivek

18

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

Verwenden Sie es dann in onCreate()Ihrer HauptfragmentActivity:

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

    RateItDialogFragment.show(this, getFragmentManager());

}

Gut! Ich würde einfach die editor.commit () einfügen, bevor ich das DialogFragment zeige, nur für den Fall, dass beim Laden des Dialogs etwas schief geht.
Narko

@narko Danke. Aktualisiert.
Mixel

Hinweis: Es kann zu einem Speicherverlust führen, wenn Sie zum Speichern gemeinsame Einstellungen verwenden. Wenn Sie dies in setPositiveButtonund sorgfältig bemerken setNegativeButton, wird mit commit in die freigegebenen Einstellungen geschrieben. Wenn Sie jedoch apply verwenden, ist dies asynchron und behält den Verweis auf die Aktivität bei, bis sie abgeschlossen ist und unmittelbar danach die Entlassung aufgerufen wird. Dismiss wird versuchen, das Fragment zu zerstören, kann dies jedoch nicht, da die Aktivität vom Prozess zum Anwenden gemeinsamer Einstellungen gehalten / verwendet wird. (Ich habe dies getragen, weil AndroidStudio den Benutzer auffordert, das Commit zum Anwenden zu ändern. Tun Sie dies nur, wenn Sie dies tun benutze eine andere Logik)
Sai

@mixel Wie ändere ich Code, um ihn in Aktivität und ohne Fragment verwenden zu können?
user1090751

7

Ich denke, was Sie versuchen zu tun, ist wahrscheinlich kontraproduktiv.

Es ist im Allgemeinen eine gute Idee, den Nutzern das Bewerten von Apps zu erleichtern, da die meisten Leute, die sich die Mühe machen, dies tun, weil ihnen die App gefällt. Es wird gemunkelt, dass die Anzahl der Bewertungen Ihre Marktbewertung beeinflusst (obwohl ich wenig Beweise dafür sehe). Wenn Benutzer durch Nörgelbildschirme zur Bewertung gezwungen werden, kann dies dazu führen, dass Benutzer den Nörgel durch Löschen einer schlechten Bewertung beseitigen.

Das Hinzufügen der Möglichkeit, eine App direkt zu bewerten, hat zu einem leichten Rückgang der numerischen Bewertungen für meine kostenlose Version und zu einem leichten Anstieg meiner kostenpflichtigen App geführt. Für die kostenlose App stiegen meine 4-Sterne-Bewertungen stärker als meine 5-Sterne-Bewertungen, da Leute, die meine App für gut, aber nicht großartig hielten, sie ebenfalls bewerteten. Die Änderung betrug ungefähr -0,2. Für die Bezahlten betrug die Änderung etwa +0,1. Ich sollte es aus der kostenlosen Version entfernen, außer ich möchte viele Kommentare bekommen.

Ich habe meine Bewertungsschaltfläche in einen Einstellungsbildschirm (Voreinstellungsbildschirm) eingefügt, in dem der normale Betrieb nicht beeinträchtigt wird. Es hat meine Bewertungsrate immer noch um den Faktor 4 oder 5 erhöht. Ich habe keinen Zweifel daran, dass ich viele Benutzer bekommen würde, die mir aus Protest schlechte Bewertungen geben würden, wenn ich versuchen würde, meine Benutzer dazu zu bringen, eine Bewertung abzugeben.


100% wahr. Das gleiche passierte auch mit meiner kostenlosen App.
Akash Varlani

7

AndroidRate ist eine Bibliothek, mit der Sie für Ihre Android-App werben können, indem Benutzer aufgefordert werden, die App nach einigen Tagen zu bewerten.

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

Die Standardbedingungen zum Anzeigen des Tarifdialogs lauten wie folgt:

  1. Die App wird mehr als 10 Tage nach der Installation gestartet. Ändern über AppRate#setInstallDays(byte).
  2. App wird mehr als 10 Mal gestartet. Ändern über AppRate#setLaunchTimes(byte).
  3. Die App wird mehr als 1 Tag nach dem Klicken auf die neutrale Schaltfläche gestartet. Ändern über AppRate#setRemindInterval(byte).
  4. App wird X-mal gestartet und X% 1 = 0. Ändern über AppRate#setRemindLaunchTimes(byte).
  5. App zeigt standardmäßig einen neutralen Dialog (Erinnere mich später). Ändern über setShowLaterButton(boolean).
  6. Festlegen des Rückrufs beim Drücken der Taste. Der gleiche Wert wie das zweite Argument von DialogInterface.OnClickListener#onClickwird im Argument von übergeben onClickButton.
  7. Durch die Einstellung AppRate#setDebug(boolean)wird sichergestellt, dass die Bewertungsanforderung bei jedem Start der App angezeigt wird. Diese Funktion ist nur für die Entwicklung! .

Optionale benutzerdefinierte Ereignisanforderungen zum Anzeigen des Dialogfelds

Sie können zusätzliche optionale Anforderungen für die Anzeige des Dialogfelds hinzufügen. Jede Anforderung kann als eindeutige Zeichenfolge hinzugefügt / referenziert werden. Sie können für jedes dieser Ereignisse eine Mindestanzahl festlegen (z. B. dreimal "action_performed", 5-mal "button_clicked" usw.).

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

Deaktivieren Sie das Flag zum Anzeigen des Dialogfelds

Wenn Sie den Dialog erneut anzeigen möchten, rufen Sie an AppRate#clearAgreeShowDialog().

AppRate.with(this).clearAgreeShowDialog();

Wenn die Taste gedrückt wird

anrufen AppRate#showRateDialog(Activity).

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

Benutzerdefinierte Ansicht festlegen

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

Spezifisches Thema

Sie können ein bestimmtes Thema verwenden, um den Dialog aufzublasen.

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

Benutzerdefinierter Dialog

Wenn Sie Ihre eigenen Dialogfeldbezeichnungen verwenden möchten, überschreiben Sie die XML-Ressourcen für Zeichenfolgen in Ihrer Anwendung.

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

Überprüfen Sie, ob Google Play verfügbar ist

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

}


3

Diese Lösung ist den oben dargestellten sehr ähnlich. Der einzige Unterschied besteht darin, dass Sie die Eingabeaufforderung des Bewertungsdialogs pro Start und Tag verzögern können. Wenn die Schaltfläche "Später erinnern" gedrückt wird, verzögere ich das Popup um 3 Tage und 10 Starts. Das Gleiche gilt für diejenigen, die ausgewählt haben, um es zu bewerten, jedoch sind die Verzögerungen länger (um den Benutzer nicht so schnell zu stören, falls er die App tatsächlich bewertet hat. Dies kann geändert werden, um nicht erneut angezeigt zu werden, dann müssen Sie Ändern Sie den Code nach Ihren Wünschen. Hoffe es hilft jemandem!

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

Die Schaltflächen haben eine bestimmte Farbe und einen bestimmten Hintergrund. Der Hintergrund ist wie in dieser XML-Datei gezeigt:

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

Quelle: Android-Ansatz für "Bewerten Sie meine Anwendung"


Was ist "Configs", es wird nicht gefunden, wenn ich es versuche.
Md Imran Choudhury

1
@ Md.ImranChoudhury Entschuldigung für die späte Antwort. Die Konfiguration ist eine private Klasse von mir, die ich für Google Analytics verwende. Sie können diese Anweisung einfach ohne Probleme entfernen!
Gustavo Baiocchi Costa

Sie sollten entweder auf die ursprüngliche Antwort verlinken oder ihm eine Gutschrift geben. stackoverflow.com/a/6920848/563735
Rohit Mandiwal


1

Wie Sie dem anderen Beitrag entnehmen können, den Sie verlinkt haben, kann die App nicht feststellen, ob der Benutzer eine Bewertung abgegeben hat oder nicht. Und das aus gutem Grund.

Denken Sie darüber nach, ob eine App erkennen kann, ob der Benutzer eine Bewertung abgegeben hat oder nicht, der Entwickler bestimmte Funktionen einschränken kann, die nur freigeschaltet werden, wenn der Benutzer eine Bewertung von 5/5 hinterlässt. Dies würde dazu führen, dass die anderen Nutzer von Google Play den Bewertungen nicht vertrauen und das Bewertungssystem untergraben.

Die alternative Lösung, die ich gesehen habe, besteht darin, dass die App den Benutzer daran erinnert, eine Bewertung abzugeben, wenn die App eine bestimmte Anzahl von Malen oder ein festgelegtes Intervall geöffnet wird. Bitten Sie den Benutzer beispielsweise bei jedem zehnten Öffnen der App, eine Bewertung abzugeben und die Schaltfläche "bereits erledigt" und "Später erinnern" anzugeben. Diese Meldung wird weiterhin angezeigt, wenn der Benutzer ihn später daran erinnert hat. Einige andere Apps-Entwickler zeigen diese Meldung mit zunehmendem Intervall an (z. B. 5, 10, 15. Mal, wenn die App geöffnet wird), denn wenn ein Benutzer zum 100. Mal, als die App geöffnet wurde, keine Bewertung abgegeben hat, ist dies der Fall wahrscheinlich wird er / sie keinen verlassen.

Diese Lösung ist nicht perfekt, aber ich denke, es ist die beste, die Sie derzeit haben. Es führt dazu, dass Sie dem Benutzer vertrauen, aber erkennen, dass die Alternative eine potenziell schlechtere Erfahrung für alle auf dem App-Markt bedeuten würde.


0

Kotlin-Version von Raghav Soods Antwort

Rater.kt

    class Rater {
      companion object {
        private const val APP_TITLE = "App Name"
        private const val APP_NAME = "com.example.name"

        private const val RATER_KEY = "rater_key"
        private const val LAUNCH_COUNTER_KEY = "launch_counter_key"
        private const val DO_NOT_SHOW_AGAIN_KEY = "do_not_show_again_key"
        private const val FIRST_LAUNCH_KEY = "first_launch_key"

        private const val DAYS_UNTIL_PROMPT: Int = 3
        private const val LAUNCHES_UNTIL_PROMPT: Int = 3

        fun start(mContext: Context) {
            val prefs: SharedPreferences = mContext.getSharedPreferences(RATER_KEY, 0)
            if (prefs.getBoolean(DO_NOT_SHOW_AGAIN_KEY, false)) {
                return
            }

            val editor: Editor = prefs.edit()

            val launchesCounter: Long = prefs.getLong(LAUNCH_COUNTER_KEY, 0) + 1;
            editor.putLong(LAUNCH_COUNTER_KEY, launchesCounter)

            var firstLaunch: Long = prefs.getLong(FIRST_LAUNCH_KEY, 0)
            if (firstLaunch == 0L) {
                firstLaunch = System.currentTimeMillis()
                editor.putLong(FIRST_LAUNCH_KEY, firstLaunch)
            }

            if (launchesCounter >= LAUNCHES_UNTIL_PROMPT) {
                if (System.currentTimeMillis() >= firstLaunch +
                    (DAYS_UNTIL_PROMPT * 24 * 60 * 60 * 1000)
                ) {
                    showRateDialog(mContext, editor)
                }
            }

            editor.apply()
        }

        fun showRateDialog(mContext: Context, editor: Editor) {
            Dialog(mContext).apply {
                setTitle("Rate $APP_TITLE")

                val ll = LinearLayout(mContext)
                ll.orientation = LinearLayout.VERTICAL

                TextView(mContext).apply {
                    text =
                        "If you enjoy using $APP_TITLE, please take a moment to rate it. Thanks for your support!"

                    width = 240
                    setPadding(4, 0, 4, 10)
                    ll.addView(this)
                }

                Button(mContext).apply {
                    text = "Rate $APP_TITLE"
                    setOnClickListener {
                        mContext.startActivity(
                            Intent(
                                Intent.ACTION_VIEW,
                                Uri.parse("market://details?id=$APP_NAME")
                            )
                        );
                        dismiss()
                    }
                    ll.addView(this)
                }

                Button(mContext).apply {
                    text = "Remind me later"
                    setOnClickListener {
                        dismiss()
                    };
                    ll.addView(this)
                }

                Button(mContext).apply {
                    text = "No, thanks"
                    setOnClickListener {
                        editor.putBoolean(DO_NOT_SHOW_AGAIN_KEY, true);
                        editor.commit()
                        dismiss()
                    };
                    ll.addView(this)
                }

                setContentView(ll)
                show()
            }
        }
    }
}

Optimierte Antwort

Rater.kt

class Rater {
    companion object {
        fun start(context: Context) {
            val prefs: SharedPreferences = context.getSharedPreferences(RATER_KEY, 0)
            if (prefs.getBoolean(DO_NOT_SHOW_AGAIN_KEY, false)) {
                return
            }

            val editor: Editor = prefs.edit()

            val launchesCounter: Long = prefs.getLong(LAUNCH_COUNTER_KEY, 0) + 1;
            editor.putLong(LAUNCH_COUNTER_KEY, launchesCounter)

            var firstLaunch: Long = prefs.getLong(FIRST_LAUNCH_KEY, 0)
            if (firstLaunch == 0L) {
                firstLaunch = System.currentTimeMillis()
                editor.putLong(FIRST_LAUNCH_KEY, firstLaunch)
            }

            if (launchesCounter >= LAUNCHES_UNTIL_PROMPT) {
                if (System.currentTimeMillis() >= firstLaunch +
                    (DAYS_UNTIL_PROMPT * 24 * 60 * 60 * 1000)
                ) {
                    showRateDialog(context, editor)
                }
            }

            editor.apply()
        }

        fun showRateDialog(context: Context, editor: Editor) {
            Dialog(context).apply {
                setTitle("Rate $APP_TITLE")
                LinearLayout(context).let { layout ->
                    layout.orientation = LinearLayout.VERTICAL
                    setDescription(context, layout)
                    setPositiveAnswer(context, layout)
                    setNeutralAnswer(context, layout)
                    setNegativeAnswer(context, editor, layout)
                    setContentView(layout)
                    show()       
                }
            }
        }

        private fun setDescription(context: Context, layout: LinearLayout) {
            TextView(context).apply {
                text = context.getString(R.string.rate_description, APP_TITLE)
                width = 240
                setPadding(4, 0, 4, 10)
                layout.addView(this)
            }
        }

        private fun Dialog.setPositiveAnswer(
            context: Context,
            layout: LinearLayout
        ) {
            Button(context).apply {
                text = context.getString(R.string.rate_now)
                setOnClickListener {
                    context.startActivity(
                        Intent(
                            Intent.ACTION_VIEW,
                            Uri.parse(context.getString(R.string.market_uri, APP_NAME))
                        )
                    );
                    dismiss()
                }
                layout.addView(this)
            }
        }

        private fun Dialog.setNeutralAnswer(
            context: Context,
            layout: LinearLayout
        ) {
            Button(context).apply {
                text = context.getString(R.string.remind_later)
                setOnClickListener {
                    dismiss()
                };
                layout.addView(this)
            }
        }

        private fun Dialog.setNegativeAnswer(
            context: Context,
            editor: Editor,
            layout: LinearLayout
        ) {
            Button(context).apply {
                text = context.getString(R.string.no_thanks)
                setOnClickListener {
                    editor.putBoolean(DO_NOT_SHOW_AGAIN_KEY, true);
                    editor.commit()
                    dismiss()
                };
                layout.addView(this)
            }
        }
    }
}

Constants.kt

object Constants {

    const val APP_TITLE = "App Name"
    const val APP_NAME = "com.example.name"

    const val RATER_KEY = "rater_key"
    const val LAUNCH_COUNTER_KEY = "launch_counter_key"
    const val DO_NOT_SHOW_AGAIN_KEY = "do_not_show_again_key"
    const val FIRST_LAUNCH_KEY = "first_launch_key"

    const val DAYS_UNTIL_PROMPT: Int = 3
    const val LAUNCHES_UNTIL_PROMPT: Int = 3

}

string.xml

<resources>
    <string name="rate_description">If you enjoy using %1$s, please take a moment to rate it. Thanks for your support!</string>
    <string name="rate_now">Rate now</string>
    <string name="no_thanks">No, thanks</string>
    <string name="remind_later">Remind me later</string>
    <string name="market_uri">market://details?id=%1$s</string>
</resources>

0

Java & Kotlin-Lösung (In-App-Überprüfungs-API von Google im Jahr 2020):

Geben Sie hier die Bildbeschreibung ein

Fügen Sie zunächst in Ihrer build.gradle(app)Datei die folgenden Abhängigkeiten hinzu (vollständige Einrichtung hier ).

dependencies {
    // This dependency is downloaded from the Google’s Maven repository.
    // So, make sure you also include that repository in your project's build.gradle file.
    implementation 'com.google.android.play:core:1.8.0'
}

Fügen Sie diese Methode hinzu zu Activity:

void askRatings() {
    ReviewManager manager = ReviewManagerFactory.create(this);
    Task<ReviewInfo> request = manager.requestReviewFlow();
    request.addOnCompleteListener(task -> {
        if (task.isSuccessful()) {
            // We can get the ReviewInfo object
            ReviewInfo reviewInfo = task.getResult();
            Task<Void> flow = manager.launchReviewFlow(this, reviewInfo);
            flow.addOnCompleteListener(task2 -> {
                // The flow has finished. The API does not indicate whether the user
                // reviewed or not, or even whether the review dialog was shown. Thus, no
                // matter the result, we continue our app flow.
            });
        } else {
            // There was some problem, continue regardless of the result.
        }
    });
}

Nennen Sie es wie jede andere Methode:

askRatings();

Kotlin-Code finden Sie hier

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.