Cara mengimplementasikan fitur Rate It di Aplikasi Android

95

Saya sedang mengembangkan Aplikasi Android. Di mana semuanya bekerja dengan benar. Aplikasi saya siap diluncurkan. Tetapi di sana saya perlu menerapkan satu fitur lagi. Saya perlu menampilkan popup yang berisi

Rate It dan Remind me later

Di sini jika ada pengguna yang menilai aplikasi di pasar maka popup tidak akan hilang. Saya telah mencari di Google dan menemukan satu tautan . Dengan ini saya mengerti bahwa tidak mungkin untuk mengetahuinya. Jadi saya butuh saran untuk ini.

Adakah yang pernah menghadapi situasi ini sebelumnya? Jika ya, apakah ada solusi atau alternatif lain untuk ini?

Naveen
sumber
Jadi, apakah Anda hanya meminta Beri nilai / ingatkan saya nanti atau Anda bertanya bagaimana cara mengetahui apakah pengguna tertentu telah memberi peringkat untuk Aplikasi Android?
wtsang02
1
saya telah menerapkan popup. tetapi bagaimana cara mengetahui apakah pengguna memberi peringkat aplikasi atau tidak
Naveen
-1 Saya tidak melihat perbedaan antara pertanyaan ini dan pertanyaan di tautan.
wtsang02
2
@ wtsang02, Semoga benar. Tapi lihat pertanyaannya. itu diminta Mar 15 2011. jadi hampir 20 bulan berlalu. Saya pikir seseorang memiliki solusi atau alternatif untuk kebutuhan saya. itu yang diposting di sini.
Naveen
Anda dapat menggunakan perpustakaan github.com/Vorlonsoft/AndroidRate ( implementation 'com.vorlonsoft:androidrate:1.0.3')
Alexander Savin

Jawaban:

182

Saya menerapkan ini beberapa waktu lalu, sampai batas tertentu. Tidak mungkin untuk mengetahui apakah pengguna telah memberi peringkat pada suatu aplikasi atau tidak, untuk mencegah peringkat menjadi mata uang (beberapa pengembang mungkin menambahkan opsi seperti "Nilai aplikasi ini dan dapatkan ini dan itu di aplikasi secara gratis").

Kelas yang saya tulis menyediakan tiga tombol, dan mengonfigurasi dialog sehingga hanya ditampilkan setelah aplikasi diluncurkan nwaktu (pengguna memiliki peluang lebih tinggi untuk menilai aplikasi jika mereka pernah menggunakannya sebelumnya. Kebanyakan dari mereka tidak mungkin untuk mengetahui apa yang dilakukannya saat pertama kali dijalankan):

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

Mengintegrasikan kelas semudah menambahkan:

AppRater.app_launched(this);

Untuk Aktivitas Anda. Ini hanya perlu ditambahkan ke satu Aktivitas di seluruh aplikasi.

Raghav Sood
sumber
1
Ini tidak mendukung banyak pengguna yang menggunakan perangkat yang sama.
AsafK
1
@AsafK Ya, tetapi beberapa pengguna yang menggunakan perangkat yang sama dapat ditangani dengan hanya menampilkan appraterdialog setelah autentikasi dan mengubah shared preferenceuntuk menyertakan alamat email google dalam key.
Stephen
1
Hai, saya punya satu pertanyaan. Mengapa Anda membuat semuanya statis? Terima kasih Raghav!
Ruchir Baronia
2
Hai, Saya mencoba kode Anda di atas. Saya telah memasukkan ke AppRater.app_launched(this);dalam onCreate()MainActivity saya . Saya juga telah mengubah jumlah peluncuran minimum yang diperlukan menjadi 2. Namun, saya tidak melihat dialog setelah 2 peluncuran aplikasi. Bisakah Anda membantu saya? Terima kasih!
Pengecualian
2
Lebih baik gunakan enum Context.MODE_PRIVATE-context.getSharedPreferences("apprater", Context.MODE_PRIVATE);
Vivek
18

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

Kemudian gunakan di onCreate()FragmentActivity utama Anda:

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

    RateItDialogFragment.show(this, getFragmentManager());

}
mixel
sumber
Bagus! Saya hanya akan meletakkan editor.commit () sebelum menampilkan DialogFragment kalau-kalau terjadi kesalahan saat memuat Dialog.
narko
@ Marko Terima kasih. Diperbarui.
mixel
Catatan: Ini dapat menyebabkan kebocoran memori jika Anda gunakan untuk menerapkan untuk menyimpan preferensi bersama. Jika Anda memperhatikan dengan hati-hati di setPositiveButtondan setNegativeButton, itu menulis ke preferensi bersama menggunakan komit tetapi jika Anda menggunakan apply yang merupakan asinkron dan akan menyimpan referensi ke aktivitas sampai selesai dan tepat setelah itu memanggil tutup. Menutup akan mencoba menghancurkan fragmen, tetapi tidak bisa karena aktivitas ditahan / digunakan oleh proses penerapan preferensi bersama. (Saya memakai ini karena AndroidStudio akan meminta pengguna untuk mengubah komit untuk menerapkan, jangan lakukan itu kecuali Anda menggunakan logika lain)
Sai
@mixel Bagaimana cara mengubah kode agar dapat digunakan dalam Aktivitas dan tanpa fragmen?
pengguna1090751
7

Saya pikir apa yang Anda coba lakukan mungkin kontra-produktif.

Memudahkan orang untuk memberi peringkat pada aplikasi umumnya merupakan ide yang bagus, karena kebanyakan orang yang repot melakukannya karena mereka menyukai aplikasi tersebut. Dikabarkan bahwa jumlah peringkat memengaruhi peringkat pasar Anda (meskipun saya melihat sedikit bukti tentang ini). Mengganggu pengguna dalam memberi peringkat - melalui layar cerewet - kemungkinan besar akan menyebabkan orang menghapus cerewet tersebut dengan memberikan peringkat yang buruk.

Menambahkan kemampuan untuk menilai aplikasi secara langsung telah menyebabkan sedikit penurunan peringkat numerik untuk versi gratis saya, dan sedikit peningkatan pada aplikasi berbayar saya. Untuk aplikasi gratis, peringkat 4 bintang saya meningkat lebih dari peringkat 5 bintang saya, karena orang-orang yang menganggap aplikasi saya bagus tetapi tidak bagus mulai memberi peringkat juga. Perubahan sekitar -0,2. Untuk bayaran, perubahan sekitar +0.1. Saya harus menghapusnya dari versi gratis, kecuali saya suka mendapatkan banyak komentar.

Saya memasukkan tombol peringkat saya ke layar pengaturan (preferensi), yang tidak memengaruhi pengoperasian normal. Itu masih meningkatkan peringkat saya dengan faktor 4 atau 5. Saya yakin jika saya mencoba mengganggu pengguna saya untuk membuat peringkat, saya akan mendapatkan banyak pengguna memberi saya peringkat buruk sebagai protes.

Peter Webb
sumber
100% benar. Hal yang sama terjadi dengan aplikasi gratis saya juga.
akash varlani
6

AndroidRate adalah pustaka untuk membantu Anda mempromosikan aplikasi Android dengan meminta pengguna untuk menilai aplikasi setelah menggunakannya selama beberapa hari.

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

Kondisi default untuk menampilkan dialog tarif adalah sebagai berikut:

  1. Aplikasi diluncurkan lebih dari 10 hari setelah pemasangan. Ubah melalui AppRate#setInstallDays(byte).
  2. Aplikasi diluncurkan lebih dari 10 kali. Ubah melalui AppRate#setLaunchTimes(byte).
  3. Aplikasi diluncurkan lebih dari 1 hari setelah tombol netral diklik. Ubah melalui AppRate#setRemindInterval(byte).
  4. Aplikasi diluncurkan X kali dan X% 1 = 0. Ubah melalui AppRate#setRemindLaunchTimes(byte).
  5. Aplikasi menampilkan dialog netral (Ingatkan saya nanti) secara default. Ubah melalui setShowLaterButton(boolean).
  6. Untuk menentukan panggilan balik saat tombol ditekan. Nilai yang sama dengan argumen kedua DialogInterface.OnClickListener#onClickakan dilewatkan dalam argumen onClickButton.
  7. Pengaturan AppRate#setDebug(boolean)akan memastikan bahwa permintaan peringkat ditampilkan setiap kali aplikasi diluncurkan. Fitur ini hanya untuk pengembangan! .

Persyaratan acara khusus opsional untuk menampilkan dialog

Anda dapat menambahkan persyaratan opsional tambahan untuk menampilkan dialog. Setiap persyaratan dapat ditambahkan / direferensikan sebagai string unik. Anda dapat menyetel jumlah minimum untuk setiap peristiwa tersebut (misalnya "action_performed" 3 kali, "button_clicked" 5 kali, dll.)

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

Hapus tanda dialog acara

Saat Anda ingin menampilkan dialog lagi, panggil AppRate#clearAgreeShowDialog().

AppRate.with(this).clearAgreeShowDialog();

Saat tombol ditekan

panggilan AppRate#showRateDialog(Activity).

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

Setel tampilan kustom

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

Tema khusus

Anda dapat menggunakan tema tertentu untuk memekarkan dialog.

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

Dialog kustom

Jika Anda ingin menggunakan label dialog Anda sendiri, ganti sumber daya string xml pada aplikasi Anda.

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

Periksa apakah Google Play tersedia

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

}
Alexander Savin
sumber
3

Solusi ini sangat mirip dengan yang disajikan di atas. Satu-satunya perbedaan adalah Anda akan dapat menunda prompt dialog peringkat per peluncuran dan hari. Jika tombol ingatkan saya nanti ditekan, maka saya akan menunda pop up selama 3 hari dan 10 peluncuran. Hal yang sama dilakukan untuk mereka yang memilih untuk menilai itu, namun penundaannya lebih lama (tidak mengganggu pengguna begitu cepat jika dia benar-benar memberi peringkat pada aplikasi. Ini dapat diubah menjadi tidak ditampilkan lagi, maka Anda harus ubah kodenya sesuai keinginan Anda). Semoga membantu seseorang!

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

Tombol memiliki warna dan latar belakang tertentu. Latar belakangnya seperti yang ditunjukkan pada file xml ini:

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

sumber: Pendekatan Android untuk "Beri nilai aplikasi saya"

Gustavo Baiocchi Costa
sumber
Apa itu "Configs" tidak ditemukan ketika saya mencoba.
Md Imran Choudhury
1
@ Md.ImranChoudhury Maaf atas balasan yang terlambat. Konfigurasi tersebut adalah kelas pribadi saya yang saya gunakan untuk analisis google. Anda bisa menghapus pernyataan itu tanpa masalah!
Gustavo Baiocchi Costa
Anda harus menautkan ke jawaban asli atau memberikan penghargaan kepadanya. stackoverflow.com/a/6920848/563735
Rohit Mandiwal
2

Solusi Java & Kotlin (API ulasan dalam aplikasi oleh Google pada tahun 2020):

masukkan deskripsi gambar di sini

Pertama, di build.gradle(app)file Anda , tambahkan dependensi berikut (penyiapan lengkap di sini )

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

Tambahkan metode ini ke 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.
        }
    });
}

Sebut saja seperti metode lainnya:

askRatings();

Kode Kotlin dapat ditemukan di sini

iLoveDocs
sumber
1

Seperti yang Anda lihat dari postingan lain yang telah Anda tautkan, tidak ada cara bagi aplikasi untuk mengetahui apakah pengguna telah meninggalkan ulasan atau tidak. Dan untuk alasan yang bagus.

Pikirkan tentang itu, jika sebuah aplikasi dapat mengetahui apakah pengguna telah meninggalkan ulasan atau tidak, pengembang dapat membatasi fitur tertentu yang hanya akan dibuka jika pengguna meninggalkan peringkat 5/5. Ini akan menyebabkan pengguna Google Play lainnya tidak mempercayai ulasan dan akan merusak sistem peringkat.

Solusi alternatif yang saya lihat adalah bahwa aplikasi mengingatkan pengguna untuk mengirimkan peringkat setiap kali aplikasi dibuka beberapa kali, atau interval yang ditentukan. Misalnya, setiap 10 kali aplikasi dibuka, minta pengguna untuk memberikan rating dan berikan tombol "sudah selesai" dan "ingatkan saya nanti". Terus tampilkan pesan ini jika pengguna telah memilih untuk mengingatkannya nanti. Beberapa pengembang aplikasi lain menampilkan pesan ini dengan interval yang meningkat (seperti, 5, 10, 15 kali aplikasi dibuka), karena jika pengguna tidak meninggalkan ulasan pada, misalnya, 100 kali aplikasi dibuka, itu kemungkinan besar dia tidak akan meninggalkannya.

Solusi ini tidak sempurna, tapi menurut saya itu yang terbaik yang Anda miliki untuk saat ini. Itu memang membuat Anda memercayai pengguna, tetapi menyadari bahwa alternatifnya akan berarti pengalaman yang berpotensi lebih buruk bagi semua orang di pasar aplikasi.

Vidhur Vohra
sumber
0

Versi Kotlin dari jawaban Raghav Sood

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

Jawaban yang dioptimalkan

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

}

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>
Victor R. Oliveira
sumber
0

Sistem Ulasan Dalam Aplikasi baru Android diluncurkan yang memungkinkan pengembang meminta ulasan Play Store tanpa meninggalkan aplikasi.

Untuk memeriksa pedoman desain dan kapan menampilkan kartu ulasan, lihat dokumen resmi

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

Untuk melaksanakan:

  • Tambahkan library play-core sebagai dependensi dalam file build.gradle Anda.
implementation 'com.google.android.play:core:1.8.0'
  • Buat ReviewManager contoh dan meminta ReviewInfo objek. Objek ReviewInfo yang akan disimpan sebelumnya dan kemudian dapat memicu "launchReviewFlow" untuk menampilkan kartu Review kepada pengguna.

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

Catatan: Disarankan untuk menunjukkan alur ulasan setelah pengguna cukup berpengalaman dengan aplikasi atau game Anda.

Kapan harus meminta peninjauan dalam aplikasi:

  • Picu aliran peninjauan dalam aplikasi setelah pengguna cukup berpengalaman dengan aplikasi atau game Anda untuk memberikan masukan yang berguna.
  • Jangan meminta pengguna secara berlebihan untuk meninjau. Pendekatan ini membantu meminimalkan frustrasi pengguna dan membatasi penggunaan API (lihat bagian tentang kuota).
  • Aplikasi Anda tidak boleh mengajukan pertanyaan apa pun kepada pengguna sebelum atau saat menampilkan tombol atau kartu rating, termasuk pertanyaan tentang pendapat mereka (seperti "Apakah Anda menyukai aplikasi ini?") Atau pertanyaan prediktif (seperti "Apakah Anda menilai aplikasi ini 5 bintang ”).

Beberapa poin sebelum menguji ini:

  • Saat menguji fungsionalitas baru, kebanyakan kami membuat proyek baru yang akan memiliki ApplicationId baru, pastikan Anda memberikan ApplicationId yang sudah dirilis dan tersedia di play store.

  • Jika Anda sebelumnya pernah memberikan masukan untuk aplikasi Anda, launchReviewFlow API ulasan dalam aplikasi tidak akan menampilkan kartu Ulasan apa pun . Ini hanya memicu acara sukses.

  • Karena batasan kuota, memanggil metode launchReviewFlow mungkin tidak selalu menampilkan dialog. Ini tidak boleh ditautkan dengan acara klik apa pun.

Arunendra
sumber
0

Pastikan hal di bawah ini diterapkan Untuk ulasan dalam aplikasi:

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

Semua perpustakaan itu bukanlah solusi untuk masalah di posting ini. Perpustakaan ini baru saja membuka halaman web ke aplikasi di google play. Sebaliknya pustaka inti Play ini memiliki antarmuka yang lebih konsisten.

Jadi saya pikir inilah masalahnya, ProGuard: ini cukup mengaburkan beberapa kelas https://stackoverflow.com/a/63650212/10117882

Phantom Lord
sumber
0

Mulai Agustus 2020, API Ulasan Dalam Aplikasi Google Play tersedia dan penerapan langsungnya benar sesuai jawaban ini .

Tetapi jika Anda ingin menambahkan beberapa logika tampilan di atasnya, gunakan Five-Star-Me library .

Setel waktu peluncuran dan hari instal dalam onCreatemetode MainActivity untuk mengonfigurasi pustaka.

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

Kemudian tempatkan panggilan metode di bawah ini pada metode onCreate / onViewCreated aktivitas / fragmen untuk menampilkan permintaan setiap kali kondisi terpenuhi.

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

masukkan deskripsi gambar di sini

Instruksi instalasi:

Anda dapat mengunduh dari jitpack.

Langkah 1: Tambahkan ini ke project (root) build.gradle.

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

Langkah 2: Tambahkan dependensi berikut ke build.gradle level modul (aplikasi) Anda.

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