Cách triển khai tính năng Xếp hạng trong Ứng dụng Android


94

Tôi đang phát triển một ứng dụng Android. Trong đó mọi thứ đang hoạt động tốt. Ứng dụng của tôi đã sẵn sàng để khởi chạy. Nhưng ở đó tôi cần triển khai thêm một tính năng nữa. Tôi cần hiển thị một cửa sổ bật lên chứa

Rate ItRemind me later

Tại đây nếu bất kỳ người dùng nào đánh giá ứng dụng trên thị trường thì cửa sổ bật lên sẽ không bị biến mất. Tôi đã tìm kiếm trong Google và tìm thấy một liên kết . Với điều này, tôi hiểu rằng không thể biết được. Vì vậy, tôi cần một gợi ý cho điều này.

Có ai đã đối mặt với tình huống này trước đây? Nếu vậy, có bất kỳ giải pháp hoặc bất kỳ thay thế nào cho điều này?


Vì vậy, bạn chỉ yêu cầu Xếp hạng / nhắc nhở tôi sau hay bạn đang yêu cầu làm thế nào để biết liệu một người dùng cụ thể đã xếp hạng một Ứng dụng Android?
wtsang02

1
tôi đã triển khai cửa sổ bật lên. nhưng làm thế nào để biết nếu một người sử dụng đánh giá ứng dụng hay không
Naveen

-1 Tôi không thấy sự khác biệt giữa câu hỏi này và câu hỏi trong liên kết.
wtsang02

2
@ wtsang02, Có thể đúng. Nhưng hãy xem câu hỏi. nó đã hỏi trên Mar 15 2011. như vậy gần 20 tháng qua. Tôi nghĩ một số người có giải pháp hoặc thay thế cho yêu cầu của tôi. đó là bạn đã đăng ở đây.
Naveen

Bạn có thể sử dụng thư viện github.com/Vorlonsoft/AndroidRate ( implementation 'com.vorlonsoft:androidrate:1.0.3')
Alexander Savin

Câu trả lời:


180

Tôi đã thực hiện điều này một thời gian trở lại, ở một mức độ nào đó. Không thể biết liệu người dùng đã xếp hạng ứng dụng hay chưa, để ngăn xếp hạng trở thành đơn vị tiền tệ (một số nhà phát triển có thể thêm tùy chọn như "Xếp hạng ứng dụng này và nhận được như vậy và tương tự trong ứng dụng miễn phí").

Lớp tôi đã viết cung cấp ba nút và định cấu hình hộp thoại để hộp thoại chỉ hiển thị sau khi ứng dụng được khởi chạy nlần (người dùng có cơ hội xếp hạng ứng dụng cao hơn nếu họ đã sử dụng nó trước đó một chút. Hầu hết chúng không chắc thậm chí biết nó làm gì trong lần chạy đầu tiên):

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

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

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

        SharedPreferences.Editor editor = prefs.edit();

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

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

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

        editor.commit();
    }   

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

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

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

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

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

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

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

Việc tích hợp lớp đơn giản như thêm:

AppRater.app_launched(this);

Đối với hoạt động của bạn. Nó chỉ cần được thêm vào một Hoạt động trong toàn bộ ứng dụng.


1
Điều này không hỗ trợ nhiều người dùng sử dụng cùng một thiết bị.
AsafK

1
@AsafK Có, nhưng có thể xử lý nhiều người dùng sử dụng cùng một thiết bị bằng cách chỉ hiển thị appraterhộp thoại sau khi xác thực và thay đổi shared preferenceđể bao gồm địa chỉ email google trong key.
stephen

1
Xin chào, tôi có một câu hỏi. Tại sao bạn làm cho mọi thứ tĩnh? Cảm ơn Raghav!
Ruchir Baronia

2
Xin chào, tôi đang thử mã ở trên của bạn. Tôi đã đặt AppRater.app_launched(this);bên trong onCreate()MainActivity của mình . Tôi cũng đã thay đổi số lần khởi chạy tối thiểu bắt buộc thành 2. Nhưng tôi không thấy hộp thoại sau 2 lần khởi chạy ứng dụng. Bạn có thể giúp tôi không? Cảm ơn!
Ngoại lệ,

1
Tốt hơn hãy sử dụng enum Context.MODE_PRIVATE-context.getSharedPreferences("apprater", Context.MODE_PRIVATE);
Vivek

18

Cái của tôi bằng 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();
    }
}

Sau đó, sử dụng nó trong onCreate()FragmentActivity chính của bạn:

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

    RateItDialogFragment.show(this, getFragmentManager());

}

Tốt! Tôi sẽ chỉ đặt editor.commit () trước khi hiển thị DialogFragment đề phòng xảy ra sự cố khi tải Hộp thoại.
narko

@narko Cảm ơn. Đã cập nhật.
mixel

Lưu ý: Nó có thể dẫn đến rò rỉ bộ nhớ nếu bạn sử dụng để áp dụng để lưu tùy chọn chia sẻ. Nếu bạn chú ý cẩn thận trong setPositiveButtonsetNegativeButton, nó đang viết cho các tùy chọn được chia sẻ bằng cách sử dụng cam kết nhưng nếu bạn sử dụng áp dụng là không đồng bộ và sẽ giữ tham chiếu đến hoạt động cho đến khi hoàn thành và ngay sau đó nó sẽ gọi loại bỏ. Bỏ qua sẽ cố gắng phá hủy phân đoạn, nhưng không thể vì hoạt động được tổ chức / sử dụng bởi quy trình áp dụng tùy chọn chia sẻ. (Tôi mặc điều này vì AndroidStudio sẽ nhắc người dùng thay đổi cam kết áp dụng, đừng làm điều đó trừ khi bạn sử dụng một số logic khác)
Sai

@mixel Làm cách nào để sửa đổi mã để có thể sử dụng trong Hoạt động và không có phân đoạn?
user1090751

7

Tôi nghĩ những gì bạn đang cố gắng làm có thể phản tác dụng.

Giúp mọi người dễ dàng xếp hạng ứng dụng nói chung là một ý tưởng hay, vì hầu hết những người bận tâm làm như vậy vì họ thích ứng dụng. Có tin đồn rằng số lượng xếp hạng ảnh hưởng đến xếp hạng thị trường của bạn (mặc dù tôi thấy ít bằng chứng về điều này). Rắc rối người dùng đánh giá - thông qua các màn hình gây khó chịu - có thể khiến mọi người xóa bỏ sự phiền phức thông qua việc để lại xếp hạng xấu.

Việc thêm khả năng xếp hạng trực tiếp ứng dụng đã khiến xếp hạng số cho phiên bản miễn phí của tôi giảm nhẹ và ứng dụng trả phí của tôi tăng nhẹ. Đối với ứng dụng miễn phí, xếp hạng 4 sao của tôi tăng nhiều hơn xếp hạng 5 sao, vì những người nghĩ rằng ứng dụng của tôi tốt nhưng không tuyệt vời cũng bắt đầu xếp hạng ứng dụng đó. Thay đổi là khoảng -0,2. Đối với trả phí, thay đổi là khoảng +0,1. Tôi nên xóa nó khỏi phiên bản miễn phí, ngoại trừ việc tôi thích nhận được nhiều bình luận.

Tôi đặt nút xếp hạng của mình vào màn hình cài đặt (tùy chọn), nơi nó không ảnh hưởng đến hoạt động bình thường. Nó vẫn làm tăng tỷ lệ xếp hạng của tôi lên 4 hoặc 5. Tôi không nghi ngờ gì rằng nếu tôi cố gắng nài nỉ người dùng của mình đưa ra xếp hạng, tôi sẽ nhận được rất nhiều người dùng xếp hạng xấu cho tôi như một sự phản đối.


đúng 100. Điều tương tự cũng xảy ra với ứng dụng miễn phí của tôi.
akash varlani

7

AndroidRate là một thư viện giúp bạn quảng bá ứng dụng Android của mình bằng cách nhắc người dùng xếp hạng ứng dụng sau khi sử dụng nó trong vài ngày.

Mô-đun 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);
  }
}

Các điều kiện mặc định để hiển thị hộp thoại tỷ lệ như sau:

  1. Ứng dụng được khởi chạy chậm hơn 10 ngày so với cài đặt. Thay đổi quaAppRate#setInstallDays(byte) .
  2. Ứng dụng được khởi chạy hơn 10 lần. Thay đổi quaAppRate#setLaunchTimes(byte) .
  3. Ứng dụng được khởi chạy hơn 1 ngày sau khi nhấp vào nút trung lập. Thay đổi quaAppRate#setRemindInterval(byte) .
  4. Ứng dụng được khởi chạy X lần và X% 1 = 0. Thay đổi qua AppRate#setRemindLaunchTimes(byte) .
  5. Ứng dụng hiển thị hộp thoại trung lập (Nhắc tôi sau) theo mặc định. Thay đổi quasetShowLaterButton(boolean) .
  6. Để chỉ định cuộc gọi lại khi nút được nhấn. Giá trị tương tự như đối số thứ hai của DialogInterface.OnClickListener#onClicksẽ được chuyển vào đối số củaonClickButton .
  7. Cài đặt AppRate#setDebug(boolean)sẽ đảm bảo rằng yêu cầu xếp hạng được hiển thị mỗi khi ứng dụng được khởi chạy. Tính năng này chỉ dành cho sự phát triển! .

Yêu cầu sự kiện tùy chỉnh tùy chọn để hiển thị hộp thoại

Bạn có thể thêm các yêu cầu tùy chọn bổ sung để hiển thị hộp thoại. Mỗi yêu cầu có thể được thêm / tham chiếu dưới dạng một chuỗi duy nhất. Bạn có thể đặt số lượng tối thiểu cho mỗi sự kiện như vậy (ví dụ: "action_performed" 3 lần, "button_clicked" 5 lần, v.v.)

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

Xóa cờ hộp thoại hiển thị

Khi bạn muốn hiển thị lại hộp thoại, hãy gọi AppRate#clearAgreeShowDialog().

AppRate.with(this).clearAgreeShowDialog();

Khi nút nhấn vào

cuộc gọi AppRate#showRateDialog(Activity).

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

Đặt chế độ xem tùy chỉnh

cuộc gọi 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();

Chủ đề cụ thể

Bạn có thể sử dụng một chủ đề cụ thể để thổi phồng hộp thoại.

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

Hộp thoại tùy chỉnh

Nếu bạn muốn sử dụng nhãn hộp thoại của riêng mình, hãy ghi đè tài nguyên xml chuỗi trên ứng dụng của bạ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>

Kiểm tra xem Google Play có khả dụng không

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

}


3

Giải pháp này rất giống với những giải pháp đã trình bày ở trên. Sự khác biệt duy nhất là bạn sẽ có thể trì hoãn lời nhắc của hộp thoại xếp hạng cho mỗi lần khởi chạy và ngày. Nếu nút nhắc tôi sau được nhấn, thì tôi sẽ trì hoãn cửa sổ bật lên trong 3 ngày và 10 lần khởi chạy. Điều tương tự cũng được thực hiện đối với những người đã chọn để xếp hạng ứng dụng đó, tuy nhiên thời gian chậm trễ lâu hơn (không làm phiền người dùng quá sớm trong trường hợp họ đã thực sự xếp hạng ứng dụng. Điều này có thể được thay đổi để không hiển thị lại, sau đó bạn sẽ phải thay đổi mã theo ý muốn của bạn). Hy vọng nó sẽ giúp ai đó!

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

Các nút có màu và nền cụ thể. Nền như được hiển thị trong tệp xml này:

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

nguồn: Phương pháp tiếp cận Android cho "Xếp hạng ứng dụng của tôi"


"Cấu hình" là gì nó không tìm thấy khi tôi thử.
Md Imran Choudhury

1
@ Md.ImranChoudhury Xin lỗi vì đã trả lời muộn. Cấu hình là một lớp riêng của tôi mà tôi sử dụng cho google analytics. Bạn chỉ có thể xóa câu lệnh đó mà không có vấn đề gì!
Gustavo Baiocchi Costa

bạn nên liên kết đến câu trả lời ban đầu hoặc ghi công cho anh ta. stackoverflow.com/a/6920848/563735
Rohit Mandiwal


1

Như bạn thấy từ bài đăng khác mà bạn đã liên kết, không có cách nào để ứng dụng biết liệu người dùng đã để lại đánh giá hay chưa. Và vì lý do chính đáng.

Hãy nghĩ về điều đó, nếu một ứng dụng có thể biết người dùng có để lại đánh giá hay không, nhà phát triển có thể hạn chế một số tính năng nhất định chỉ được mở khóa nếu người dùng để lại xếp hạng 5/5. Điều này sẽ khiến những người dùng khác của Google Play không tin tưởng vào các bài đánh giá và sẽ phá hoại hệ thống xếp hạng.

Các giải pháp thay thế mà tôi đã thấy là ứng dụng nhắc người dùng gửi xếp hạng bất cứ khi nào ứng dụng được mở trong một số lần cụ thể hoặc một khoảng thời gian nhất định. Ví dụ: vào mỗi lần thứ 10 mở ứng dụng, hãy yêu cầu người dùng để lại xếp hạng và cung cấp nút "đã xong" và "nhắc tôi sau". Tiếp tục hiển thị thông báo này nếu người dùng đã chọn để nhắc họ sau. Một số nhà phát triển ứng dụng khác hiển thị thông báo này với khoảng thời gian tăng dần (như, 5, 10, 15 lần mở ứng dụng), bởi vì nếu người dùng chưa để lại đánh giá về ví dụ: lần thứ 100 ứng dụng được mở, đó là có thể là anh ấy / anh ấy sẽ không rời bỏ nó.

Giải pháp này không phải là hoàn hảo, nhưng tôi nghĩ đó là giải pháp tốt nhất bạn có lúc này. Nó khiến bạn tin tưởng người dùng, nhưng nhận ra rằng giải pháp thay thế sẽ có nghĩa là trải nghiệm có thể tồi tệ hơn cho mọi người trong chợ ứng dụng.


1

Giải pháp Java & Kotlin (API đánh giá trong ứng dụng của Google vào năm 2020):

nhập mô tả hình ảnh ở đây

Đầu tiên, trong build.gradle(app)tệp của bạn , hãy thêm các phần phụ thuộc sau (thiết lập đầy đủ tại đây )

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

Thêm phương pháp này vào 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.
        }
    });
}

Gọi nó giống như bất kỳ phương pháp nào khác:

askRatings();

Có thể tìm thấy mã Kotlin tại đây


0

Phiên bản Kotlin của câu trả lời của 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()
            }
        }
    }
}

Câu trả lời được tối ưu hóa

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>
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.