[android] Android 앱에서 Rate It 기능을 구현하는 방법

Android 앱을 개발 중입니다. 모든 것이 올바르게 작동합니다. 내 앱을 실행할 준비가되었습니다. 하지만 거기에 하나 이상의 기능을 구현해야합니다. 다음을 포함하는 팝업을 표시해야합니다.

Rate ItRemind me later

여기에서 사용자가 시장에서 앱을 평가하면 팝업이 사라지지 않습니다. Google에서 검색 한 결과 링크가 하나 있습니다. 이것으로 나는 알 수 없다는 것을 이해합니다. 그래서 이것에 대한 제안이 필요합니다.

전에 이런 상황에 직면 한 사람이 있습니까? 그렇다면 이에 대한 해결책이나 대안이 있습니까?



답변

나는 이것을 얼마 전에 구현했습니다. 평점이 통화가되는 것을 방지하기 위해 사용자가 앱을 평가했는지 여부를 알 수 없습니다 (일부 개발자는 “이 앱을 평가하고 앱에서 무료로 받기”와 같은 옵션을 추가 할 수 있음).

내가 작성한 클래스는 3 개의 버튼을 제공하고 앱이 실행 된 후에 만 ​​표시되도록 대화 상자를 구성합니다 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();
    }
}

클래스 통합은 다음을 추가하는 것만 큼 간단합니다.

AppRater.app_launched(this);

당신의 활동에. 전체 앱에서 하나의 활동에만 추가하면됩니다.


답변

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

그런 다음 onCreate()기본 FragmentActivity 에서 사용하십시오 .

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

    RateItDialogFragment.show(this, getFragmentManager());

}


답변

나는 당신이하려는 것이 아마도 비생산적이라고 생각합니다.

사람들이 앱을 쉽게 평가할 수 있도록하는 것이 일반적으로 좋은 생각입니다. 대부분의 사람들이 앱을 좋아하기 때문에 평가하기 때문입니다. 등급의 수가 시장 등급에 영향을 미친다는 소문이 있습니다 (이에 대한 증거는 거의 보이지 않지만). 사용자가 잔소리 화면을 통해 등급을 매기는 것은 사람들이 나쁜 등급을 남김으로써 잔소리를 없애 게 할 수 있습니다.

앱을 직접 평가하는 기능을 추가하면 무료 버전의 평점 수치가 약간 감소하고 유료 앱이 약간 증가했습니다. 무료 앱의 경우 내 앱이 훌륭하다고 생각했지만 좋지 않다고 생각하는 사람들도 평가하기 시작하면서 내 별 4 개 평점이 5 개 별 평점보다 높았습니다. 변화는 약 -0.2였습니다. 유료의 경우 변동은 약 +0.1입니다. 댓글을 많이받는 것을 좋아한다는 점을 제외하고는 무료 버전에서 삭제해야합니다.

평가 버튼을 설정 (기본 설정) 화면에 넣어 정상적인 작동에 영향을주지 않습니다. 여전히 내 평가율을 4 또는 5 배 증가 시켰습니다. 사용자에게 등급을 매기도록 잔소리를한다면 많은 사용자가 나에게 나쁜 평가를 내놓는 항의를 받게 될 것입니다.


답변

AndroidRate 는 앱을 며칠 동안 사용한 후 사용자에게 평가를 요청하여 Android 앱을 홍보하는 데 도움이되는 라이브러리입니다.

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

속도 대화 상자를 표시하는 기본 조건은 다음과 같습니다.

  1. 앱이 설치보다 10 일 이상 늦게 실행됩니다. 다음을 통해 변경AppRate#setInstallDays(byte) .
  2. 앱이 10 회 이상 실행되었습니다. 다음을 통해 변경AppRate#setLaunchTimes(byte) .
  3. 중립 버튼을 클릭 한 후 1 일이 지난 후 앱이 실행됩니다. 다음을 통해 변경AppRate#setRemindInterval(byte) .
  4. 앱이 X 번 실행되고 X % 1 = 0입니다. AppRate#setRemindLaunchTimes(byte) 입니다..
  5. 앱은 기본적으로 중립 대화 상자 (나중에 알림)를 표시합니다. 다음을 통해 변경setShowLaterButton(boolean) .
  6. 버튼을 눌렀을 때 콜백을 지정합니다. 의 두 번째 인수와 동일한 값이의 인수에 DialogInterface.OnClickListener#onClick전달됩니다.onClickButton .
  7. 설정 AppRate#setDebug(boolean)하면 앱이 실행될 때마다 등급 요청이 표시됩니다. 이 기능은 개발 전용입니다! .

대화 상자 표시를위한 선택적 사용자 지정 이벤트 요구 사항

대화 상자를 표시하기위한 추가 선택적 요구 사항을 추가 할 수 있습니다. 각 요구 사항은 고유 한 문자열로 추가 / 참조 할 수 있습니다. 이러한 각 이벤트에 대해 최소 횟수를 설정할 수 있습니다 (예 : “action_performed”3 회, “button_clicked”5 회 등).

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

대화 상자 표시 플래그 지우기

대화 상자를 다시 표시하려면을 호출하십시오 AppRate#clearAgreeShowDialog().

AppRate.with(this).clearAgreeShowDialog();

버튼을 누르면

전화 AppRate#showRateDialog(Activity).

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

사용자 지정보기 설정

전화 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();

특정 테마

특정 테마를 사용하여 대화 상자를 부 풀릴 수 있습니다.

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

사용자 정의 대화 상자

고유 한 대화 레이블을 사용하려면 애플리케이션에서 문자열 xml 리소스를 재정의합니다.

<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를 사용할 수 있는지 확인

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

}


답변

이 라이브러리를 사용하면 간단하고 쉽습니다 ..
https://github.com/hotchemi/Android-Rate

종속성을 추가하여 ..

dependencies {
  compile 'com.github.hotchemi:android-rate:0.5.6'
}


답변

이 솔루션은 위에 제시된 솔루션과 매우 유사합니다. 유일한 차이점은 실행 및 날짜별로 평가 대화 상자의 프롬프트를 지연 할 수 있다는 것입니다. 나중에 알림 버튼을 누르면 팝업이 3 일 동안 지연되고 10 번 실행됩니다. 평가하기로 선택한 사람들에게도 똑같이 적용되지만 지연 시간이 더 길어집니다 (사용자가 실제로 앱을 평가 한 경우 너무 빨리 사용자를 괴롭히지 않습니다. 다시 표시되지 않도록 변경할 수 있습니다. 코드를 원하는대로 변경하십시오). 누군가에게 도움이되기를 바랍니다!

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

버튼에는 특정 색상과 배경이 있습니다. 배경은 다음 xml 파일에 표시된 것과 같습니다.

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:padding="10dp"
    android:shape="rectangle" >

    <solid android:color="#2E78B9" />

    <corners
        android:bottomLeftRadius="6dp"
        android:bottomRightRadius="6dp"
        android:topLeftRadius="6dp"
        android:topRightRadius="6dp" />

</shape>

출처 : “내 애플리케이션 평가”에 대한 Android 접근 방식


답변

이 쉬운 솔루션을 사용하고 있습니다. 이 라이브러리를 gradle로 추가 할 수 있습니다 :
https://github.com/fernandodev/easy-rating-dialog

compile 'com.github.fernandodev.easyratingdialog:easyratingdialog:+'