Android Uygulamasında Puan Ver özelliği nasıl uygulanır?


97

Bir Android Uygulaması geliştiriyorum. Her şeyin doğru çalıştığı. Uygulamam başlatılmaya hazır. Ama orada bir özelliği daha uygulamam gerekiyor. Şunları içeren bir pop-up görüntülemem gerekiyor

Rate It ve Remind me later

Burada, herhangi bir kullanıcı uygulamayı pazarda derecelendirirse, pop-up kaybolmayacaktır. Google'da aradım ve bir bağlantı buldum . Bununla bilmenin mümkün olmadığını anlıyorum. Bu yüzden bunun için bir öneriye ihtiyacım var.

Bu durumla daha önce karşılaşan oldu mu? Varsa, bunun için herhangi bir çözüm veya alternatif var mı?


1
Öyleyse sadece Oy ver / bana daha sonra hatırlat mı istiyorsun yoksa belirli bir kullanıcının bir Android Uygulamasını derecelendirip derecelendirmediğini nasıl anlayacağını mı soruyorsun?
wtsang02

1
açılır pencereyi uyguladım. ancak bir kullanıcının uygulamayı derecelendirip derecelendirmediğini nasıl anlarsınız
Naveen

-1 Bu soruyla bağlantıdaki soru arasındaki farkı görmüyorum.
wtsang02

2
@ wtsang02, onun doğru olabilir. Ama soruya bakın. soruldu Mar 15 2011. yani neredeyse 20 ay geçti. Sanırım birisinin ihtiyacım için bir çözümü veya alternatifi var. bu yi burada yayınlanmıştır.
Naveen

Kitaplığı kullanabilirsiniz github.com/Vorlonsoft/AndroidRate ( implementation 'com.vorlonsoft:androidrate:1.0.3')
Alexander Savin

Yanıtlar:


183

Bunu bir süre önce uyguladım. Kullanıcıların bir uygulamaya puan verip vermediğini bilmek, puanların para birimi haline gelmesini önlemek için imkansızdır (bazı geliştiriciler "Bu uygulamaya oy ver ve bunu uygulamada ücretsiz olarak al" gibi bir seçenek ekleyebilir).

Yazdığım sınıf, üç düğme sağlar ve iletişim kutusunu yalnızca uygulama başlatıldıktan sonra gösterilecek şekilde yapılandırır n(kullanıcıların uygulamayı biraz daha önce kullanmışlarsa, uygulamayı derecelendirme şansı daha yüksektir. Çoğu olası değildir. ilk çalıştırmada ne yaptığını bile bilmek için):

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

Sınıfı entegre etmek, eklemek kadar basittir:

AppRater.app_launched(this);

Faaliyetinize. Tüm uygulamada yalnızca bir Aktiviteye eklenmesi gerekir.


1
Bu, aynı cihazı kullanan birden fazla kullanıcıyı desteklemez.
AsafK

1
@AsafK Evet, ancak aynı cihazı kullanan birden fazla kullanıcı, yalnızca appraterkimlik doğrulamadan sonra iletişim kutusu gösterilerek shared preferenceve google e-posta adresini key.
stephen

1
Merhaba, sadece bir sorum var. Neden her şeyi statik yaptın? Teşekkürler Raghav!
Ruchir Baronia

2
Merhaba, yukarıdaki kodu deniyorum. Ben koyduk AppRater.app_launched(this);benim içeride onCreate()MainActivity arasında. Ayrıca gerekli minimum başlatma sayısını 2 olarak değiştirdim. Ancak, 2 uygulama başlatıldıktan sonra iletişim kutusunu görmüyorum. Bana yardım edebilir misin? Teşekkürler!
istisna

2
Numaralamayı daha iyi kullanın Context.MODE_PRIVATE-context.getSharedPreferences("apprater", Context.MODE_PRIVATE);
Vivek

18

DialogFragment kullanan benim:

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

Ardından onCreate()ana FragmentActivity'nizde kullanın:

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

    RateItDialogFragment.show(this, getFragmentManager());

}

İyi bir! Dialog'u yüklerken bir şeyler ters giderse diye DialogFragment'ı göstermeden önce editor.commit () koyardım.
narko

@narko Teşekkürler. Güncellenmiş.
mixel

Not: Paylaşılan tercihi kaydetmek için kullanırsanız bellek sızıntısına neden olabilir. Dikkatli bir şekilde fark ederseniz setPositiveButtonve setNegativeButtoncommit kullanarak paylaşılan tercihlere yazıyorsa, ancak eşzamansız olan application'ı kullanırsanız ve tamamlanıncaya kadar aktiviteye referansı tutacak ve hemen ardından dismiss'i çağıracaktır. Dismiss, parçayı yok etmeye çalışacak, ancak etkinlik paylaşılan tercih uygulama işlemi tarafından tutulduğu / kullanıldığı için yapamaz. (Bunu giydim çünkü AndroidStudio, kullanıcıdan uygulama için taahhüdü değiştirmesini isteyecek, siz yapmadıkça yapmayın başka bir mantık kullanın)
Sai

@mixel Etkinlik içinde ve parça olmadan kullanabilmek için kod nasıl değiştirilir?
user1090751

7

Bence yapmaya çalıştığınız şey muhtemelen ters etki yaratıyor.

İnsanların uygulamaları derecelendirmesini kolaylaştırmak genellikle iyi bir fikirdir, zira çoğu insan bunu uygulamayı beğendikleri için yapar. Derecelendirme sayısının pazar puanınızı etkilediği söyleniyor (bununla ilgili çok az kanıt görmeme rağmen). Kullanıcıları derecelendirmeye zorlamak - nag ekranları aracılığıyla - insanların kötü bir derecelendirme bırakarak dırdırı gidermesine neden olabilir.

Bir uygulamayı doğrudan derecelendirme özelliğini eklemek, ücretsiz sürümümün sayısal puanlarında hafif bir düşüşe ve ücretli uygulamamda hafif bir artışa neden oldu. Ücretsiz uygulama için 4 yıldız puanım, 5 yıldız puanımdan daha fazla arttı, çünkü uygulamamın iyi olduğunu ancak harika olmadığını düşünen insanlar da oy vermeye başladı. Değişim yaklaşık -0,2 idi. Ödenen için değişiklik +0.1 civarındaydı. Çok sayıda yorum almayı sevmem dışında, ücretsiz sürümden kaldırmalıyım.

Derecelendirme düğmemi, normal çalışmayı etkilemediği bir ayarlar (tercih) ekranına koydum. Yine de derecelendirme oranımı 4 veya 5 kat artırdı. Hiç şüphem yok ki, eğer kullanıcılarımı bir derecelendirme yapmaları için dürtmeye çalışırsam, protesto olarak çok sayıda kullanıcının bana kötü derecelendirmeler vermesini sağlayacağım.


100 doğru. Aynı şey benim ücretsiz uygulamamda da oldu.
akash varlani

6

AndroidRate , kullanıcılardan uygulamayı birkaç gün kullandıktan sonra derecelendirmelerini isteyerek android uygulamanızı tanıtmanıza yardımcı olacak bir kitaplıktır.

Modül 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);
  }
}

Hız iletişim kutusunu göstermek için varsayılan koşullar aşağıdaki gibidir:

  1. Uygulama, kurulumdan 10 gün sonra başlatılır. Yoluyla değiştir AppRate#setInstallDays(byte).
  2. Uygulama 10'dan fazla kez başlatıldı. Yoluyla değiştir AppRate#setLaunchTimes(byte).
  3. Uygulama, nötr düğmenin tıklanmasından 1 gün sonra başlatılır. Yoluyla değiştir AppRate#setRemindInterval(byte).
  4. Uygulama X kez ve X% 1 = 0 başlatılır AppRate#setRemindLaunchTimes(byte). İle değiştirin .
  5. Uygulama varsayılan olarak nötr iletişim kutusunu (Daha sonra hatırlat) gösterir. Yoluyla değiştir setShowLaterButton(boolean).
  6. Düğmeye basıldığında geri aramayı belirtmek için. İkinci argüman ile aynı değer argümanında DialogInterface.OnClickListener#onClickiletilecektir onClickButton.
  7. Ayarlama AppRate#setDebug(boolean), uygulama her başlatıldığında derecelendirme isteğinin gösterilmesini sağlar. Bu özellik yalnızca geliştirme içindir! .

İletişim kutusunu göstermek için isteğe bağlı özel etkinlik gereksinimleri

İletişim kutusunu göstermek için ek isteğe bağlı gereksinimler ekleyebilirsiniz. Her gereksinim benzersiz bir dizge olarak eklenebilir / referans gösterilebilir. Bu tür olayların her biri için bir minimum sayı ayarlayabilirsiniz (örneğin, "eylem_ gerçekleştirildi" 3 kez, "düğme_ tıklandı" 5 kez vb.)

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

Göster diyalog bayrağını temizle

Diyaloğu tekrar göstermek istediğinizde arayın AppRate#clearAgreeShowDialog().

AppRate.with(this).clearAgreeShowDialog();

Düğmeye basıldığında

çağrı AppRate#showRateDialog(Activity).

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

Özel görünümü ayarlayın

çağrı 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();

Belirli tema

Diyaloğu şişirmek için belirli bir tema kullanabilirsiniz.

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

Özel iletişim kutusu

Kendi iletişim kutusu etiketlerinizi kullanmak istiyorsanız, uygulamanızda string xml kaynaklarını geçersiz kılın.

<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'in kullanılabilir olup olmadığını kontrol edin

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

}

4

Java ve Kotlin çözümü (2020'de Google'dan uygulama içi inceleme API'si):

görüntü açıklamasını buraya girin

Öncelikle, build.gradle(app)dosyanıza aşağıdaki bağımlılıkları ekleyin (tam kurulum burada )

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

Bu yöntemi şuna ekleyin 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.
        }
    });
}

Başka bir yöntem gibi çağırın:

askRatings();

Kotlin kodu burada bulunabilir


Ancak bu inceleme iletişim kutusu yalnızca bir kez görüntüleniyor.Bu uygulama içi inceleme iletişim kutusunu uygulamada birden çok kez nasıl gösterebiliriz?
user2162130

@ user2162130 Bunu henüz test etmedim, ancak iletişim kutusunun birden fazla kez açılmasını önlemek için Google tarafından kasıtlı olarak yapılması gerektiğini düşünüyorum, aksi takdirde geliştiricilerin inceleme istemeye devam etmeleri kullanıcılar için çok zor olacaktır.
iDonKnow

1
Merhaba çözümü buldum, Uygulama içi derecelendirme iletişim kutusunu test etmek için bir apk yükleyebileceğimiz Google'ın dahili Uygulama Paylaşımını kullanarak uygulamayı test edebiliriz. Yükledikten sonra uygulamayı test edebiliriz, uygulamada yaptığınız durumunuza göre her seferinde Uygulama içi derecelendirme iletişim kutusunu gösterecektir.
user2162130

bunun için minimum API gereksinimi ???
AG-Developer

1
@ AG-Developer Henüz kontrol etmedi, ancak API olması gerektiğinden eminim> = 21
iDonKnow


3

Bu çözüm, yukarıda sunulanlara çok benzer. Tek fark, başlatma ve gün başına derecelendirme iletişim kutusunun istemini erteleyebilmenizdir. Daha sonra hatırlat düğmesine basılırsa, açılır pencereyi 3 gün ve 10 başlatma için erteleyeceğim. Aynısı, derecelendirmeyi seçenler için de yapılır, ancak gecikmeler daha uzundur (uygulamayı gerçekten derecelendirmiş olması durumunda kullanıcıyı bu kadar çabuk rahatsız etmemek. Bu, bir daha gösterilmeyecek şekilde değiştirilebilir, o zaman yapmanız gerekir kodu beğeninize göre değiştirin). Umarım birine yardımcı olur!

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

Düğmelerin belirli bir rengi ve arka planı vardır. Arka plan, bu xml dosyasında gösterildiği gibidir:

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

kaynak: "Uygulamamı derecelendir" için Android yaklaşımı


"Yapılandırmalar" nedir, denediğimde bulunamıyor.
Md Imran Choudhury

1
@ Md.ImranChoudhury Geç cevap için özür dilerim. Yapılandırmalar, google analytics için kullandığım özel bir sınıfım. Bu ifadeyi sorunsuz bir şekilde kaldırabilirsiniz!
Gustavo Baiocchi Costa

Ya orijinal cevaba bağlanmalı ya da ona itibar etmelisiniz. stackoverflow.com/a/6920848/563735
Rohit Mandiwal


1

Bağladığınız diğer gönderiden de gördüğünüz gibi, uygulamanın kullanıcının bir yorum bırakıp bırakmadığını bilmesinin bir yolu yoktur. Ve iyi bir sebepten dolayı.

Bir düşünün, bir uygulama kullanıcının bir yorum bırakıp bırakmadığını anlayabilirse, geliştirici, yalnızca kullanıcı 5/5 puan bıraktığında kilidi açılacak belirli özellikleri kısıtlayabilir. Bu, Google Play'in diğer kullanıcılarının yorumlara güvenmemesine neden olacak ve derecelendirme sistemini zayıflatacaktır.

Gördüğüm alternatif çözümler, uygulamanın kullanıcıya, uygulama belirli sayıda açıldığında veya belirli bir aralıkta her açıldığında bir derecelendirme göndermesini hatırlatmasıdır. Örneğin, uygulama her 10. açıldığında, kullanıcıdan bir derecelendirme bırakmasını ve "zaten yapıldı" ve "daha sonra hatırlat" düğmesi sağlamasını isteyin. Kullanıcı ona daha sonra hatırlatmayı seçtiyse bu mesajı göstermeye devam edin. Diğer bazı uygulama geliştiricileri, bu mesajı artan bir aralıkla gösterir (örneğin, uygulamanın açıldığı 5, 10, 15'inci gibi), çünkü bir kullanıcı, örneğin uygulamanın 100. açılışında bir inceleme bırakmadıysa, Muhtemelen bir tanesini terk etmeyecek.

Bu çözüm mükemmel değil, ama bence şimdilik sahip olduğunuz en iyi çözüm. Sizi kullanıcıya güvenmeye yönlendirir, ancak alternatifin uygulama pazarındaki herkes için potansiyel olarak daha kötü bir deneyim anlamına geleceğini fark eder.


1

Ağustos 2020 itibarıyla, Google Play'in Uygulama İçi İnceleme API'sı kullanıma sunulmuştur ve basit uygulaması bu yanıta göre doğrudur .

Ancak, üstüne biraz görüntüleme mantığı eklemek isterseniz, Beş Yıldızlı Ben kitaplığını kullanın.

onCreateKitaplığı yapılandırmak için MainActivity yönteminde başlatma zamanlarını ve yükleme günlerini ayarlayın .

  FiveStarMe.with(this)
      .setInstallDays(0) // default 10, 0 means install day.
      .setLaunchTimes(3) // default 10
      .setDebug(false) // default false
      .monitor();

Ardından, koşullar karşılandığında istemi göstermek için aşağıdaki yöntem çağrısını herhangi bir etkinlik / parçanın onCreate / onViewCreated yöntemine yerleştirin.

FiveStarMe.showRateDialogIfMeetsConditions(this); //Where *this* is the current activity.

görüntü açıklamasını buraya girin

Kurulum Talimatları:

Jitpack'ten indirebilirsiniz.

Adım 1: Bunu project (kök) build.gradle'a ekleyin.

allprojects {
  repositories {
    ...
    maven { url 'https://jitpack.io' }
  }
}

Adım 2: Aşağıdaki bağımlılığı modül (uygulama) düzeyi build.gradle'a ekleyin.

dependencies {
  implementation 'com.github.numerative:Five-Star-Me:2.0.0'
}


Açıklamanızı ve kütüphane yazarının verdiği açıklamayı (github'da) takip ettim, ancak InAppRating mesajını alamadım. Lib'i MainActivity # onCreate yönteminde başlattım sonra onu fragement olarak çağırıyorum. Parçalarla ilgili herhangi bir sorun var mı?
Souf ROCHDI

1
Bu istemi görmek için apk'yi en azından dahili uygulama paylaşımına veya dahili test kanalına yüklemeniz gerekir. developer.android.com/guide/playcore/in-app-review/test
Michael Hathi

Teşekkür ederim @Michael işe yaradı. resmi belgelerde anlatılan test bölümüne dikkat etmedim.
Souf ROCHDI

0

Raghav Sood'un cevabının Kotlin versiyonu

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

Optimize edilmiş cevap

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

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

}

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

Android'in geliştiricilerin uygulamadan çıkmadan Play Store incelemeleri istemesine olanak tanıyan yeni Uygulama İçi İnceleme sistemi başlatıldı.

Tasarım yönergelerini ve bir inceleme kartının ne zaman görüntüleneceğini kontrol etmek için resmi belgeye bakın

https://developer.android.com/guide/playcore/in-app-review

Uygulamaya:

  • Play-core kitaplığını build.gradle dosyanıza bağımlılık olarak ekleyin.
implementation 'com.google.android.play:core:1.8.0'
  • ReviewManager örneği oluşturun ve ReviewInfo nesnesi talep edin . Önbelleğe alınacak ReviewInfo nesnesi ve ardından Review kartını kullanıcıya sunmak için "launchReviewFlow" öğesini tetikleyebilir .

     private var reviewInfo: ReviewInfo? = null
    
     val manager = ReviewManagerFactory.create(context)
    
     val request = manager.requestReviewFlow()
    
     requestFlow.addOnCompleteListener { request ->
         if (request.isSuccessful) {
             //Received ReviewInfo object
             reviewInfo = request.result
         } else {
             //Problem in receiving object
             reviewInfo = null
         }
    
     reviewInfo?.let {
         val flow = reviewManager.launchReviewFlow(this@MainActivity, it)
         flow.addOnCompleteListener {
             //Irrespective of the result, the app flow should continue
         }
     }
    

Not: İnceleme akışının, kullanıcı uygulamanızı veya oyununuzu yeterince deneyimledikten sonra gösterilmesi önerilir.

Uygulama içi inceleme ne zaman istenmeli:

  • Bir kullanıcı, yararlı geri bildirim sağlamak için uygulamanızı veya oyununuzu yeterince deneyimledikten sonra uygulama içi inceleme akışını tetikleyin.
  • Kullanıcıdan aşırı derecede inceleme istemeyin. Bu yaklaşım, kullanıcı hayal kırıklığını en aza indirmeye ve API kullanımını sınırlamaya yardımcı olur (kotalarla ilgili bölüme bakın).
  • Uygulamanız, kullanıcıya derecelendirme düğmesini veya kartını sunmadan önce veya sunarken, fikirleri hakkındaki sorular ("Uygulamayı beğendiniz mi?" Gibi) veya tahmine dayalı sorular ("Bu uygulamayı 5 yıldız verir misiniz?" Gibi ”).

Bunu test etmeden önce birkaç nokta:

  • Yeni işlevleri test ederken, çoğunlukla yeni ApplicationId'ye sahip olacak yeni bir proje oluşturuyoruz, zaten piyasaya sürülen ve oyun mağazasında bulunan bir ApplicationId verdiğinizden emin olun.

  • Geçmişte uygulamanız için geri bildirim verdiyseniz , uygulama içi inceleme API'sinin launchReviewFlow herhangi bir İnceleme kartı göstermez . Basitçe bir başarı olayını tetikler.

  • Kota sınırlamaları nedeniyle, launchReviewFlow yönteminin çağrılması her zaman bir iletişim kutusu görüntülemeyebilir. Herhangi bir tıklama olayı ile bağlantılı olmamalıdır.


0

Uygulama içi incelemeler için aşağıdakilerin uygulandığından emin olun:

implementation 'com.google.android.play:core:1.8.0'

OnCreate

public void RateApp(Context mContext) {
    try {
        ReviewManager manager = ReviewManagerFactory.create(mContext);
        manager.requestReviewFlow().addOnCompleteListener(new OnCompleteListener<ReviewInfo>() {
            @Override
            public void onComplete(@NonNull Task<ReviewInfo> task) {
                if(task.isSuccessful()){
                    ReviewInfo reviewInfo = task.getResult();
                    manager.launchReviewFlow((Activity) mContext, reviewInfo).addOnFailureListener(new OnFailureListener() {
                        @Override
                        public void onFailure(Exception e) {
                            Toast.makeText(mContext, "Rating Failed", Toast.LENGTH_SHORT).show();
                        }
                    }).addOnCompleteListener(new OnCompleteListener<Void>() {
                        @Override
                        public void onComplete(@NonNull Task<Void> task) {
                            Toast.makeText(mContext, "Review Completed, Thank You!", Toast.LENGTH_SHORT).show();
                        }
                    });
                }

            }
        }).addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(Exception e) {
                Toast.makeText(mContext, "In-App Request Failed", Toast.LENGTH_SHORT).show();
            }
        });
    } catch (ActivityNotFoundException e) {
        e.printStackTrace();
    }
}

0

Tüm bu kütüphaneler, bu gönderideki sorunun çözümü değil. Bu kitaplıklar, google play'deki uygulamaya bir web sayfası açar. Bunun yerine, bu Play çekirdek kitaplığı daha tutarlı bir arayüze sahiptir.

Bence sorun bu, ProGuard: bazı sınıfları yeterince karartıyor https://stackoverflow.com/a/63650212/10117882

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.