├── .gitignore
├── .travis.yml
├── CHANGELOG.md
├── LICENSE
├── README.md
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── library
├── .gitignore
├── build.gradle
├── gradle.properties
└── src
│ ├── androidTest
│ └── java
│ │ └── hotchemi
│ │ └── android
│ │ └── rate
│ │ └── UriHelperTest.java
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── hotchemi
│ │ └── android
│ │ └── rate
│ │ ├── AppRate.java
│ │ ├── DialogManager.java
│ │ ├── DialogOptions.java
│ │ ├── IntentHelper.java
│ │ ├── OnClickButtonListener.java
│ │ ├── PreferenceHelper.java
│ │ ├── StoreType.java
│ │ ├── UriHelper.java
│ │ └── Utils.java
│ └── res
│ ├── values-cs
│ └── strings.xml
│ ├── values-de
│ └── strings.xml
│ ├── values-es
│ └── strings.xml
│ ├── values-eu
│ └── strings.xml
│ ├── values-fa
│ └── strings.xml
│ ├── values-fr
│ └── strings.xml
│ ├── values-it
│ └── strings.xml
│ ├── values-iw
│ └── strings.xml
│ ├── values-ja
│ └── strings.xml
│ ├── values-ko
│ └── strings.xml
│ ├── values-pl
│ └── strings.xml
│ ├── values-pt
│ └── strings.xml
│ ├── values-ru
│ └── strings.xml
│ ├── values-tr
│ └── strings.xml
│ ├── values-uk
│ └── strings.xml
│ ├── values-v21
│ └── themes.xml
│ ├── values-vi
│ └── strings.xml
│ ├── values-zh
│ └── strings.xml
│ └── values
│ └── strings.xml
├── sample
├── .gitignore
├── build.gradle
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── hotchemi
│ │ └── android
│ │ └── rate
│ │ └── sample
│ │ └── MainActivity.java
│ └── res
│ ├── drawable-hdpi
│ └── ic_launcher.png
│ ├── drawable-mdpi
│ └── ic_launcher.png
│ ├── drawable-xhdpi
│ └── ic_launcher.png
│ ├── drawable-xxhdpi
│ └── ic_launcher.png
│ ├── layout
│ └── activity_main.xml
│ ├── values-w820dp
│ └── dimens.xml
│ └── values
│ ├── dimens.xml
│ └── strings.xml
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | # project file
2 | .gradle
3 | local.properties
4 |
5 | # android studio
6 | .idea/
7 | *.iml
8 |
9 | # mac
10 | .DS_Store
11 |
12 | /build
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: android
2 | jdk: oraclejdk8
3 |
4 | android:
5 | components:
6 | - tools
7 | - platform-tools
8 | - build-tools-23.0.2
9 | - android-23
10 | - extra-google-google_play_services
11 | - extra-android-m2repository
12 | - extra-android-support
13 | - extra-google-m2repository
14 | - sys-img-armeabi-v7a-android-21
15 |
16 | before_script:
17 | - echo no | android create avd --force -n test -t android-21 --abi armeabi-v7a
18 | - emulator -avd test -no-audio -no-window &
19 | - android-wait-for-emulator
20 | - adb shell input keyevent 82 &
21 |
22 | script:
23 | - ./gradlew clean connectedCheck
24 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # ChangeLog
2 |
3 | - 2015/12/05 1.0.1
4 | - Fix https://github.com/hotchemi/Android-Rate/pull/101.
5 | - Fix https://github.com/hotchemi/Android-Rate/pull/103.
6 | - 2016/03/20 1.0.0
7 | - Delete event tracking.
8 | - Add [#80](https://github.com/hotchemi/Android-Rate/pull/80).
9 | - Add [#84](https://github.com/hotchemi/Android-Rate/pull/84).
10 | - Add [#89](https://github.com/hotchemi/Android-Rate/pull/89).
11 | - Fix [#86](https://github.com/hotchemi/Android-Rate/pull/86).
12 | - Add [#91](https://github.com/hotchemi/Android-Rate/pull/91).
13 | - Fix [#79](https://github.com/hotchemi/Android-Rate/issues/79).
14 | - 2015/12/05 0.5.6
15 | - Add #78.
16 | - 2015/10/27 0.5.5
17 | - Fix #72.
18 | - Fix #73.
19 | - 2015/10/12 0.5.4
20 | - Add `AppRate.setAgreeShowDialog`.
21 | - 2015/08/11 0.5.3
22 | - Add `AppRate.setCancelable`.
23 | - 2015/07/28 0.5.2
24 | - Fix tiny bug.
25 | - 2015/07/26 0.5.1
26 | - [Custom resource ids #61](https://github.com/hotchemi/Android-Rate/pull/61)
27 | - 2015/06/28 0.5.0
28 | - Fix the bug that text button overflows in material theme.
29 | - 2015/01/19 0.4.3
30 | - [Add passSignificantEventAndConditions method.](https://github.com/hotchemi/Android-Rate/commit/9ca6375cbf25117a5f43afcc9651897d6bdf5888)
31 | - Improvement of internal processing.
32 | - 2014/11/25 0.4.2
33 | - 2014/08/23 0.4.1
34 | - 2014/08/09 0.4.0
35 | - 2014/08/02 0.3.3
36 | - 2014/07/23 0.3.2
37 | - 2014/07/05 0.3.1
38 | - 2014/07/03 0.3.0
39 | - 2014/07/02 0.2.1
40 | - 2014/06/20 0.2.0
41 | - 2014/06/19 0.1.3
42 | - 2014/06/16 0.1.2
43 | - 2014/06/15 0.1.1
44 | - 2014/05/25 0.1.0
45 | - 2014/04/13 0.0.6
46 | - 2014/04/12 0.0.5
47 | - 2014/04/07 0.0.4
48 | - 2014/02/13 0.0.3
49 | - 2014/02/12 0.0.2
50 | - 2014/02/11 0.0.1
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Shintaro Katafuchi
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Android-Rate
2 | ============
3 |
4 | [](https://travis-ci.org/hotchemi/Android-Rate)
5 |
6 | Android-Rate is a library to help you promote your android app by prompting users to rate the app after using it for a few days.
7 |
8 | 
9 |
10 | ## Install
11 |
12 | You can download from maven central.
13 |
14 | ${latest.version} is 
15 |
16 | ```groovy
17 | dependencies {
18 | compile 'com.github.hotchemi:android-rate:{latest.version}'
19 | }
20 | ```
21 |
22 | ## Usage
23 |
24 | ### Configuration
25 |
26 | Android-Rate provides methods to configure its behavior.
27 |
28 | ```java
29 | @Override
30 | protected void onCreate(Bundle savedInstanceState) {
31 | super.onCreate(savedInstanceState);
32 | setContentView(R.layout.activity_main);
33 |
34 | AppRate.with(this)
35 | .setInstallDays(0) // default 10, 0 means install day.
36 | .setLaunchTimes(3) // default 10
37 | .setRemindInterval(2) // default 1
38 | .setShowLaterButton(true) // default true
39 | .setDebug(false) // default false
40 | .setOnClickButtonListener(new OnClickButtonListener() { // callback listener.
41 | @Override
42 | public void onClickButton(int which) {
43 | Log.d(MainActivity.class.getName(), Integer.toString(which));
44 | }
45 | })
46 | .monitor();
47 |
48 | // Show a dialog if meets conditions
49 | AppRate.showRateDialogIfMeetsConditions(this);
50 | }
51 | ```
52 |
53 | The default conditions to show rate dialog is as below:
54 |
55 | 1. App is launched more than 10 days later than installation. Change via `AppRate#setInstallDays(int)`.
56 | 2. App is launched more than 10 times. Change via `AppRate#setLaunchTimes(int)`.
57 | 3. App is launched more than 2 days after neutral button clicked. Change via `AppRate#setRemindInterval(int)`.
58 | 4. App shows neutral dialog(Remind me later) by default. Change via `setShowLaterButton(boolean)`.
59 | 5. To specify the callback when the button is pressed. The same value as the second argument of `DialogInterface.OnClickListener#onClick` will be passed in the argument of `onClickButton`.
60 | 6. Setting `AppRate#setDebug(boolean)` will ensure that the rating request is shown each time the app is launched. **This feature is only development!**.
61 |
62 | ### Clear show dialog flag
63 |
64 | When you want to show the dialog again, call `AppRate#clearAgreeShowDialog()`.
65 |
66 | ```java
67 | AppRate.with(this).clearAgreeShowDialog();
68 | ```
69 |
70 | ### When the button presses on
71 |
72 | call `AppRate#showRateDialog(Activity)`.
73 |
74 | ```java
75 | AppRate.with(this).showRateDialog(this);
76 | ```
77 |
78 | ### Set custom view
79 |
80 | call `AppRate#setView(View)`.
81 |
82 | ```java
83 | LayoutInflater inflater = (LayoutInflater)this.getSystemService(LAYOUT_INFLATER_SERVICE);
84 | View view = inflater.inflate(R.layout.custom_dialog, (ViewGroup)findViewById(R.id.layout_root));
85 | AppRate.with(this).setView(view).monitor();
86 | ```
87 |
88 | ### Custom dialog
89 |
90 | If you want to use your own dialog labels, override string xml resources on your application.
91 |
92 | ```xml
93 |
94 | Rate this app
95 | 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!
96 | Rate It Now
97 | Remind Me Later
98 | No, Thanks
99 |
100 | ```
101 |
102 | ## Language
103 |
104 | Android-Rate currently supports the following languages:
105 |
106 | - English
107 | - Czech
108 | - German
109 | - Spanish
110 | - Basque
111 | - Persian
112 | - French
113 | - Italy
114 | - Hebrew
115 | - Japanese
116 | - Korean
117 | - Polish
118 | - Portuguese
119 | - Russian
120 | - Turkish
121 | - Ukrainian
122 | - Vietnamese
123 | - Chinese
124 |
125 | ## Support
126 |
127 | Android-Rate supports API level 9 and up.
128 |
129 | ## Sample
130 |
131 | Please try to move the [sample](https://github.com/hotchemi/Android-Rate/tree/master/sample).
132 |
133 | ## Contribute
134 |
135 | 1. Fork it
136 | 2. Create your feature branch (`git checkout -b my-new-feature`)
137 | 3. Commit your changes (`git commit -am 'Added some feature'`)
138 | 4. Push to the branch (`git push origin my-new-feature`)
139 | 5. Create new Pull Request
140 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | repositories {
3 | mavenCentral()
4 | }
5 | dependencies {
6 | classpath 'com.android.tools.build:gradle:1.3.0'
7 | }
8 | }
9 |
10 | allprojects {
11 | repositories {
12 | mavenCentral()
13 | }
14 | }
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | VERSION_NAME=1.0.1
2 | VERSION_CODE=28
3 | GROUP=com.github.hotchemi
4 | POM_DESCRIPTION=Library for Android applications, which provides rating dialog.
5 | POM_URL=https://github.com/hotchemi/Android-Rate
6 | POM_SCM_URL=https://github.com/hotchemi/Android-Rate
7 | POM_SCM_CONNECTION=scm:git@github.com:hotchemi/Android-Rate.git
8 | POM_SCM_DEV_CONNECTION=scm:git@github.com:hotchemi/Android-Rate.git
9 | POM_LICENCE_NAME=The MIT License
10 | POM_LICENCE_URL=http://opensource.org/licenses/mit-license.php
11 | POM_LICENCE_DIST=repo
12 | POM_DEVELOPER_ID=hotchemi
13 | POM_DEVELOPER_NAME=Shintaro Katafuchi
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hotchemi/Android-Rate/5d327976fd5106b8edfee5e5f7ad05dfe66c7857/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Mon Jan 19 05:44:15 JST 2015
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.6-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # For Cygwin, ensure paths are in UNIX format before anything is touched.
46 | if $cygwin ; then
47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
48 | fi
49 |
50 | # Attempt to set APP_HOME
51 | # Resolve links: $0 may be a link
52 | PRG="$0"
53 | # Need this for relative symlinks.
54 | while [ -h "$PRG" ] ; do
55 | ls=`ls -ld "$PRG"`
56 | link=`expr "$ls" : '.*-> \(.*\)$'`
57 | if expr "$link" : '/.*' > /dev/null; then
58 | PRG="$link"
59 | else
60 | PRG=`dirname "$PRG"`"/$link"
61 | fi
62 | done
63 | SAVED="`pwd`"
64 | cd "`dirname \"$PRG\"`/" >&-
65 | APP_HOME="`pwd -P`"
66 | cd "$SAVED" >&-
67 |
68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
69 |
70 | # Determine the Java command to use to start the JVM.
71 | if [ -n "$JAVA_HOME" ] ; then
72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
73 | # IBM's JDK on AIX uses strange locations for the executables
74 | JAVACMD="$JAVA_HOME/jre/sh/java"
75 | else
76 | JAVACMD="$JAVA_HOME/bin/java"
77 | fi
78 | if [ ! -x "$JAVACMD" ] ; then
79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
80 |
81 | Please set the JAVA_HOME variable in your environment to match the
82 | location of your Java installation."
83 | fi
84 | else
85 | JAVACMD="java"
86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
87 |
88 | Please set the JAVA_HOME variable in your environment to match the
89 | location of your Java installation."
90 | fi
91 |
92 | # Increase the maximum file descriptors if we can.
93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
94 | MAX_FD_LIMIT=`ulimit -H -n`
95 | if [ $? -eq 0 ] ; then
96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
97 | MAX_FD="$MAX_FD_LIMIT"
98 | fi
99 | ulimit -n $MAX_FD
100 | if [ $? -ne 0 ] ; then
101 | warn "Could not set maximum file descriptor limit: $MAX_FD"
102 | fi
103 | else
104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
105 | fi
106 | fi
107 |
108 | # For Darwin, add options to specify how the application appears in the dock
109 | if $darwin; then
110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
111 | fi
112 |
113 | # For Cygwin, switch paths to Windows format before running java
114 | if $cygwin ; then
115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
158 | function splitJvmOpts() {
159 | JVM_OPTS=("$@")
160 | }
161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
163 |
164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
165 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/library/.gitignore:
--------------------------------------------------------------------------------
1 | build/
--------------------------------------------------------------------------------
/library/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 |
3 | android {
4 | compileSdkVersion 23
5 | buildToolsVersion '23.0.2'
6 | defaultConfig {
7 | minSdkVersion 9
8 | targetSdkVersion 23
9 | }
10 | }
11 |
12 | apply from: 'https://raw.github.com/chrisbanes/gradle-mvn-push/master/gradle-mvn-push.gradle'
--------------------------------------------------------------------------------
/library/gradle.properties:
--------------------------------------------------------------------------------
1 | POM_NAME=Android-Rate
2 | POM_ARTIFACT_ID=android-rate
3 | POM_PACKAGING=aar
--------------------------------------------------------------------------------
/library/src/androidTest/java/hotchemi/android/rate/UriHelperTest.java:
--------------------------------------------------------------------------------
1 | package hotchemi.android.rate;
2 |
3 | import android.net.Uri;
4 | import android.test.AndroidTestCase;
5 |
6 | /**
7 | * Unit test for {@link hotchemi.android.rate.UriHelper}
8 | */
9 | public class UriHelperTest extends AndroidTestCase {
10 |
11 | private static final String GOOGLE_PLAY = "https://play.google.com/store/apps/details?id=";
12 |
13 | public void testGetGooglePlayUri() {
14 | {
15 | Uri uri = UriHelper.getGooglePlay("");
16 | assertEquals(uri.toString(), GOOGLE_PLAY);
17 | }
18 | {
19 | Uri uri = UriHelper.getGooglePlay(null);
20 | assertNull(uri);
21 | }
22 | {
23 | final String packageName = "hotchemi.android.rate";
24 | Uri uri = UriHelper.getGooglePlay(packageName);
25 | assertEquals(uri.toString(), GOOGLE_PLAY + packageName);
26 | }
27 | }
28 | }
--------------------------------------------------------------------------------
/library/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/library/src/main/java/hotchemi/android/rate/AppRate.java:
--------------------------------------------------------------------------------
1 | package hotchemi.android.rate;
2 |
3 | import android.app.Activity;
4 | import android.content.Context;
5 | import android.view.View;
6 |
7 | import java.util.Date;
8 |
9 | import static hotchemi.android.rate.DialogManager.create;
10 | import static hotchemi.android.rate.PreferenceHelper.getInstallDate;
11 | import static hotchemi.android.rate.PreferenceHelper.getIsAgreeShowDialog;
12 | import static hotchemi.android.rate.PreferenceHelper.getLaunchTimes;
13 | import static hotchemi.android.rate.PreferenceHelper.getRemindInterval;
14 | import static hotchemi.android.rate.PreferenceHelper.isFirstLaunch;
15 | import static hotchemi.android.rate.PreferenceHelper.setInstallDate;
16 |
17 | public final class AppRate {
18 |
19 | private static AppRate singleton;
20 |
21 | private final Context context;
22 |
23 | private final DialogOptions options = new DialogOptions();
24 |
25 | private int installDate = 10;
26 |
27 | private int launchTimes = 10;
28 |
29 | private int remindInterval = 1;
30 |
31 | private boolean isDebug = false;
32 |
33 | private AppRate(Context context) {
34 | this.context = context.getApplicationContext();
35 | }
36 |
37 | public static AppRate with(Context context) {
38 | if (singleton == null) {
39 | synchronized (AppRate.class) {
40 | if (singleton == null) {
41 | singleton = new AppRate(context);
42 | }
43 | }
44 | }
45 | return singleton;
46 | }
47 |
48 | public static boolean showRateDialogIfMeetsConditions(Activity activity) {
49 | boolean isMeetsConditions = singleton.isDebug || singleton.shouldShowRateDialog();
50 | if (isMeetsConditions) {
51 | singleton.showRateDialog(activity);
52 | }
53 | return isMeetsConditions;
54 | }
55 |
56 | private static boolean isOverDate(long targetDate, int threshold) {
57 | return new Date().getTime() - targetDate >= threshold * 24 * 60 * 60 * 1000;
58 | }
59 |
60 | public AppRate setLaunchTimes(int launchTimes) {
61 | this.launchTimes = launchTimes;
62 | return this;
63 | }
64 |
65 | public AppRate setInstallDays(int installDate) {
66 | this.installDate = installDate;
67 | return this;
68 | }
69 |
70 | public AppRate setRemindInterval(int remindInterval) {
71 | this.remindInterval = remindInterval;
72 | return this;
73 | }
74 |
75 | public AppRate setShowLaterButton(boolean isShowNeutralButton) {
76 | options.setShowNeutralButton(isShowNeutralButton);
77 | return this;
78 | }
79 |
80 | public AppRate setShowNeverButton(boolean isShowNeverButton) {
81 | options.setShowNegativeButton(isShowNeverButton);
82 | return this;
83 | }
84 |
85 | public AppRate setShowTitle(boolean isShowTitle) {
86 | options.setShowTitle(isShowTitle);
87 | return this;
88 | }
89 |
90 | public AppRate clearAgreeShowDialog() {
91 | PreferenceHelper.setAgreeShowDialog(context, true);
92 | return this;
93 | }
94 |
95 | public AppRate clearSettingsParam() {
96 | PreferenceHelper.setAgreeShowDialog(context, true);
97 | PreferenceHelper.clearSharedPreferences(context);
98 | return this;
99 | }
100 |
101 | public AppRate setAgreeShowDialog(boolean clear) {
102 | PreferenceHelper.setAgreeShowDialog(context, clear);
103 | return this;
104 | }
105 |
106 | public AppRate setView(View view) {
107 | options.setView(view);
108 | return this;
109 | }
110 |
111 | public AppRate setOnClickButtonListener(OnClickButtonListener listener) {
112 | options.setListener(listener);
113 | return this;
114 | }
115 |
116 | public AppRate setTitle(int resourceId) {
117 | options.setTitleResId(resourceId);
118 | return this;
119 | }
120 |
121 | public AppRate setTitle(String title) {
122 | options.setTitleText(title);
123 | return this;
124 | }
125 |
126 | public AppRate setMessage(int resourceId) {
127 | options.setMessageResId(resourceId);
128 | return this;
129 | }
130 |
131 | public AppRate setMessage(String message) {
132 | options.setMessageText(message);
133 | return this;
134 | }
135 |
136 | public AppRate setTextRateNow(int resourceId) {
137 | options.setTextPositiveResId(resourceId);
138 | return this;
139 | }
140 |
141 | public AppRate setTextRateNow(String positiveText) {
142 | options.setPositiveText(positiveText);
143 | return this;
144 | }
145 |
146 | public AppRate setTextLater(int resourceId) {
147 | options.setTextNeutralResId(resourceId);
148 | return this;
149 | }
150 |
151 | public AppRate setTextLater(String neutralText) {
152 | options.setNeutralText(neutralText);
153 | return this;
154 | }
155 |
156 | public AppRate setTextNever(int resourceId) {
157 | options.setTextNegativeResId(resourceId);
158 | return this;
159 | }
160 |
161 | public AppRate setTextNever(String negativeText) {
162 | options.setNegativeText(negativeText);
163 | return this;
164 | }
165 |
166 | public AppRate setCancelable(boolean cancelable) {
167 | options.setCancelable(cancelable);
168 | return this;
169 | }
170 |
171 | public AppRate setStoreType(StoreType appstore) {
172 | options.setStoreType(appstore);
173 | return this;
174 | }
175 |
176 | public void monitor() {
177 | if (isFirstLaunch(context)) {
178 | setInstallDate(context);
179 | }
180 | PreferenceHelper.setLaunchTimes(context, getLaunchTimes(context) + 1);
181 | }
182 |
183 | public void showRateDialog(Activity activity) {
184 | if (!activity.isFinishing()) {
185 | create(activity, options).show();
186 | }
187 | }
188 |
189 | public boolean shouldShowRateDialog() {
190 | return getIsAgreeShowDialog(context) &&
191 | isOverLaunchTimes() &&
192 | isOverInstallDate() &&
193 | isOverRemindDate();
194 | }
195 |
196 | private boolean isOverLaunchTimes() {
197 | return getLaunchTimes(context) >= launchTimes;
198 | }
199 |
200 | private boolean isOverInstallDate() {
201 | return isOverDate(getInstallDate(context), installDate);
202 | }
203 |
204 | private boolean isOverRemindDate() {
205 | return isOverDate(getRemindInterval(context), remindInterval);
206 | }
207 |
208 | public boolean isDebug() {
209 | return isDebug;
210 | }
211 |
212 | public AppRate setDebug(boolean isDebug) {
213 | this.isDebug = isDebug;
214 | return this;
215 | }
216 |
217 | }
218 |
--------------------------------------------------------------------------------
/library/src/main/java/hotchemi/android/rate/DialogManager.java:
--------------------------------------------------------------------------------
1 | package hotchemi.android.rate;
2 |
3 | import android.app.AlertDialog;
4 | import android.app.Dialog;
5 | import android.content.Context;
6 | import android.content.DialogInterface;
7 | import android.content.Intent;
8 | import android.view.View;
9 |
10 | import static hotchemi.android.rate.IntentHelper.createIntentForAmazonAppstore;
11 | import static hotchemi.android.rate.IntentHelper.createIntentForGooglePlay;
12 | import static hotchemi.android.rate.PreferenceHelper.setAgreeShowDialog;
13 | import static hotchemi.android.rate.PreferenceHelper.setRemindInterval;
14 | import static hotchemi.android.rate.Utils.getDialogBuilder;
15 |
16 | final class DialogManager {
17 |
18 | private DialogManager() {
19 | }
20 |
21 | static Dialog create(final Context context, final DialogOptions options) {
22 | AlertDialog.Builder builder = getDialogBuilder(context);
23 | builder.setMessage(options.getMessageText(context));
24 |
25 | if (options.shouldShowTitle()) builder.setTitle(options.getTitleText(context));
26 |
27 | builder.setCancelable(options.getCancelable());
28 |
29 | View view = options.getView();
30 | if (view != null) builder.setView(view);
31 |
32 | final OnClickButtonListener listener = options.getListener();
33 |
34 | builder.setPositiveButton(options.getPositiveText(context), new DialogInterface.OnClickListener() {
35 | @Override
36 | public void onClick(DialogInterface dialog, int which) {
37 | final Intent intentToAppstore = options.getStoreType() == StoreType.GOOGLEPLAY ?
38 | createIntentForGooglePlay(context) : createIntentForAmazonAppstore(context);
39 | context.startActivity(intentToAppstore);
40 | setAgreeShowDialog(context, false);
41 | if (listener != null) listener.onClickButton(which);
42 | }
43 | });
44 |
45 | if (options.shouldShowNeutralButton()) {
46 | builder.setNeutralButton(options.getNeutralText(context), new DialogInterface.OnClickListener() {
47 | @Override
48 | public void onClick(DialogInterface dialog, int which) {
49 | setRemindInterval(context);
50 | if (listener != null) listener.onClickButton(which);
51 | }
52 | });
53 | }
54 |
55 | if (options.shouldShowNegativeButton()) {
56 | builder.setNegativeButton(options.getNegativeText(context), new DialogInterface.OnClickListener() {
57 | @Override
58 | public void onClick(DialogInterface dialog, int which) {
59 | setAgreeShowDialog(context, false);
60 | if (listener != null) listener.onClickButton(which);
61 | }
62 | });
63 | }
64 |
65 | return builder.create();
66 | }
67 |
68 | }
--------------------------------------------------------------------------------
/library/src/main/java/hotchemi/android/rate/DialogOptions.java:
--------------------------------------------------------------------------------
1 | package hotchemi.android.rate;
2 |
3 | import android.content.Context;
4 | import android.view.View;
5 |
6 | import java.lang.ref.Reference;
7 | import java.lang.ref.WeakReference;
8 |
9 | final class DialogOptions {
10 |
11 | private boolean showNeutralButton = true;
12 |
13 | private boolean showNegativeButton = true;
14 |
15 | private boolean showTitle = true;
16 |
17 | private boolean cancelable = false;
18 |
19 | private StoreType storeType = StoreType.GOOGLEPLAY;
20 |
21 | private int titleResId = R.string.rate_dialog_title;
22 |
23 | private int messageResId = R.string.rate_dialog_message;
24 |
25 | private int textPositiveResId = R.string.rate_dialog_ok;
26 |
27 | private int textNeutralResId = R.string.rate_dialog_cancel;
28 |
29 | private int textNegativeResId = R.string.rate_dialog_no;
30 |
31 | private String titleText = null;
32 |
33 | private String messageText = null;
34 |
35 | private String positiveText = null;
36 |
37 | private String neutralText = null;
38 |
39 | private String negativeText = null;
40 |
41 | private View view;
42 |
43 | private Reference listener;
44 |
45 | public boolean shouldShowNeutralButton() {
46 | return showNeutralButton;
47 | }
48 |
49 | public void setShowNeutralButton(boolean showNeutralButton) {
50 | this.showNeutralButton = showNeutralButton;
51 | }
52 |
53 | public boolean shouldShowNegativeButton() {
54 | return showNegativeButton;
55 | }
56 |
57 | public void setShowNegativeButton(boolean showNegativeButton) {
58 | this.showNegativeButton = showNegativeButton;
59 | }
60 |
61 | public boolean shouldShowTitle() {
62 | return showTitle;
63 | }
64 |
65 | public void setShowTitle(boolean showTitle) {
66 | this.showTitle = showTitle;
67 | }
68 |
69 | public boolean getCancelable() {
70 | return cancelable;
71 | }
72 |
73 | public void setCancelable(boolean cancelable) {
74 | this.cancelable = cancelable;
75 | }
76 |
77 | public StoreType getStoreType() {
78 | return storeType;
79 | }
80 |
81 | public void setStoreType( StoreType appstore ) {
82 | storeType = appstore;
83 | }
84 |
85 | public int getTitleResId() {
86 | return titleResId;
87 | }
88 |
89 | public void setTitleResId(int titleResId) {
90 | this.titleResId = titleResId;
91 | }
92 |
93 | public int getMessageResId() {
94 | return messageResId;
95 | }
96 |
97 | public void setMessageResId(int messageResId) {
98 | this.messageResId = messageResId;
99 | }
100 |
101 | public int getTextPositiveResId() {
102 | return textPositiveResId;
103 | }
104 |
105 | public void setTextPositiveResId(int textPositiveResId) {
106 | this.textPositiveResId = textPositiveResId;
107 | }
108 |
109 | public int getTextNeutralResId() {
110 | return textNeutralResId;
111 | }
112 |
113 | public void setTextNeutralResId(int textNeutralResId) {
114 | this.textNeutralResId = textNeutralResId;
115 | }
116 |
117 | public int getTextNegativeResId() {
118 | return textNegativeResId;
119 | }
120 |
121 | public void setTextNegativeResId(int textNegativeResId) {
122 | this.textNegativeResId = textNegativeResId;
123 | }
124 |
125 | public View getView() {
126 | return view;
127 | }
128 |
129 | public void setView(View view) {
130 | this.view = view;
131 | }
132 |
133 | public OnClickButtonListener getListener() {
134 | return listener != null ? listener.get() : null;
135 | }
136 |
137 | public void setListener(OnClickButtonListener listener) {
138 | this.listener = new WeakReference<>(listener);
139 | }
140 |
141 | public String getTitleText(Context context) {
142 | if (titleText == null) {
143 | return context.getString(titleResId);
144 | }
145 | return titleText;
146 | }
147 |
148 | public void setTitleText(String titleText) {
149 | this.titleText = titleText;
150 | }
151 |
152 | public String getMessageText(Context context) {
153 | if (messageText == null) {
154 | return context.getString(messageResId);
155 | }
156 | return messageText;
157 | }
158 |
159 | public void setMessageText(String messageText) {
160 | this.messageText = messageText;
161 | }
162 |
163 | public String getPositiveText(Context context) {
164 | if (positiveText == null) {
165 | return context.getString(textPositiveResId);
166 | }
167 | return positiveText;
168 | }
169 |
170 | public void setPositiveText(String positiveText) {
171 | this.positiveText = positiveText;
172 | }
173 |
174 | public String getNeutralText(Context context) {
175 | if (neutralText == null) {
176 | return context.getString(textNeutralResId);
177 | }
178 | return neutralText;
179 | }
180 |
181 | public void setNeutralText(String neutralText) {
182 | this.neutralText = neutralText;
183 | }
184 |
185 | public String getNegativeText(Context context) {
186 | if (negativeText == null) {
187 | return context.getString(textNegativeResId);
188 | }
189 | return negativeText;
190 | }
191 |
192 | public void setNegativeText(String negativeText) {
193 | this.negativeText = negativeText;
194 | }
195 | }
196 |
--------------------------------------------------------------------------------
/library/src/main/java/hotchemi/android/rate/IntentHelper.java:
--------------------------------------------------------------------------------
1 | package hotchemi.android.rate;
2 |
3 | import android.content.Context;
4 | import android.content.Intent;
5 |
6 | import static hotchemi.android.rate.UriHelper.getGooglePlay;
7 | import static hotchemi.android.rate.UriHelper.getAmazonAppstore;
8 | import static hotchemi.android.rate.UriHelper.isPackageExists;
9 |
10 | final class IntentHelper {
11 |
12 | private static final String GOOGLE_PLAY_PACKAGE_NAME = "com.android.vending";
13 |
14 | private IntentHelper() {
15 | }
16 |
17 | static Intent createIntentForGooglePlay(Context context) {
18 | String packageName = context.getPackageName();
19 | Intent intent = new Intent(Intent.ACTION_VIEW, getGooglePlay(packageName));
20 | if (isPackageExists(context, GOOGLE_PLAY_PACKAGE_NAME)) {
21 | intent.setPackage(GOOGLE_PLAY_PACKAGE_NAME);
22 | }
23 | return intent;
24 | }
25 |
26 | static Intent createIntentForAmazonAppstore(Context context) {
27 | String packageName = context.getPackageName();
28 | return new Intent(Intent.ACTION_VIEW, getAmazonAppstore(packageName));
29 | }
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/library/src/main/java/hotchemi/android/rate/OnClickButtonListener.java:
--------------------------------------------------------------------------------
1 | package hotchemi.android.rate;
2 |
3 | public interface OnClickButtonListener {
4 |
5 | void onClickButton(int which);
6 |
7 | }
--------------------------------------------------------------------------------
/library/src/main/java/hotchemi/android/rate/PreferenceHelper.java:
--------------------------------------------------------------------------------
1 | package hotchemi.android.rate;
2 |
3 | import android.content.Context;
4 | import android.content.SharedPreferences;
5 | import android.content.SharedPreferences.Editor;
6 |
7 | import java.util.Date;
8 |
9 | final class PreferenceHelper {
10 |
11 | private static final String PREF_FILE_NAME = "android_rate_pref_file";
12 |
13 | private static final String PREF_KEY_INSTALL_DATE = "android_rate_install_date";
14 |
15 | private static final String PREF_KEY_LAUNCH_TIMES = "android_rate_launch_times";
16 |
17 | private static final String PREF_KEY_IS_AGREE_SHOW_DIALOG = "android_rate_is_agree_show_dialog";
18 |
19 | private static final String PREF_KEY_REMIND_INTERVAL = "android_rate_remind_interval";
20 |
21 | private PreferenceHelper() {
22 | }
23 |
24 | static SharedPreferences getPreferences(Context context) {
25 | return context.getSharedPreferences(PREF_FILE_NAME, Context.MODE_PRIVATE);
26 | }
27 |
28 | static Editor getPreferencesEditor(Context context) {
29 | return getPreferences(context).edit();
30 | }
31 |
32 | /**
33 | * Clear data in shared preferences.
34 | *
35 | * @param context context
36 | */
37 | static void clearSharedPreferences(Context context) {
38 | SharedPreferences.Editor editor = getPreferencesEditor(context);
39 | editor.remove(PREF_KEY_INSTALL_DATE);
40 | editor.remove(PREF_KEY_LAUNCH_TIMES);
41 | editor.apply();
42 | }
43 |
44 | /**
45 | * Set agree flag about show dialog.
46 | * If it is false, rate dialog will never shown unless data is cleared.
47 | *
48 | * @param context context
49 | * @param isAgree agree with showing rate dialog
50 | */
51 | static void setAgreeShowDialog(Context context, boolean isAgree) {
52 | SharedPreferences.Editor editor = getPreferencesEditor(context);
53 | editor.putBoolean(PREF_KEY_IS_AGREE_SHOW_DIALOG, isAgree);
54 | editor.apply();
55 | }
56 |
57 | static boolean getIsAgreeShowDialog(Context context) {
58 | return getPreferences(context).getBoolean(PREF_KEY_IS_AGREE_SHOW_DIALOG, true);
59 | }
60 |
61 | static void setRemindInterval(Context context) {
62 | SharedPreferences.Editor editor = getPreferencesEditor(context);
63 | editor.remove(PREF_KEY_REMIND_INTERVAL);
64 | editor.putLong(PREF_KEY_REMIND_INTERVAL, new Date().getTime());
65 | editor.apply();
66 | }
67 |
68 | static long getRemindInterval(Context context) {
69 | return getPreferences(context).getLong(PREF_KEY_REMIND_INTERVAL, 0);
70 | }
71 |
72 | static void setInstallDate(Context context) {
73 | SharedPreferences.Editor editor = getPreferencesEditor(context);
74 | editor.putLong(PREF_KEY_INSTALL_DATE, new Date().getTime());
75 | editor.apply();
76 | }
77 |
78 | static long getInstallDate(Context context) {
79 | return getPreferences(context).getLong(PREF_KEY_INSTALL_DATE, 0);
80 | }
81 |
82 | static void setLaunchTimes(Context context, int launchTimes) {
83 | SharedPreferences.Editor editor = getPreferencesEditor(context);
84 | editor.putInt(PREF_KEY_LAUNCH_TIMES, launchTimes);
85 | editor.apply();
86 | }
87 |
88 | static int getLaunchTimes(Context context) {
89 | return getPreferences(context).getInt(PREF_KEY_LAUNCH_TIMES, 0);
90 | }
91 |
92 | static boolean isFirstLaunch(Context context) {
93 | return getPreferences(context).getLong(PREF_KEY_INSTALL_DATE, 0) == 0L;
94 | }
95 |
96 | }
--------------------------------------------------------------------------------
/library/src/main/java/hotchemi/android/rate/StoreType.java:
--------------------------------------------------------------------------------
1 | package hotchemi.android.rate;
2 |
3 | public enum StoreType {
4 | GOOGLEPLAY,
5 | AMAZON
6 | }
--------------------------------------------------------------------------------
/library/src/main/java/hotchemi/android/rate/UriHelper.java:
--------------------------------------------------------------------------------
1 | package hotchemi.android.rate;
2 |
3 | import android.content.Context;
4 | import android.content.pm.ApplicationInfo;
5 | import android.content.pm.PackageManager;
6 | import android.net.Uri;
7 |
8 | import java.util.List;
9 |
10 | final class UriHelper {
11 |
12 | private static final String GOOGLE_PLAY = "https://play.google.com/store/apps/details?id=";
13 |
14 | private static final String AMAZON_APPSTORE = "amzn://apps/android?p=";
15 |
16 | private UriHelper() {
17 | }
18 |
19 | static Uri getGooglePlay(String packageName) {
20 | return packageName == null ? null : Uri.parse(GOOGLE_PLAY + packageName);
21 | }
22 |
23 | static Uri getAmazonAppstore(String packageName) {
24 | return packageName == null ? null : Uri.parse(AMAZON_APPSTORE + packageName);
25 | }
26 |
27 | static boolean isPackageExists(Context context, String targetPackage) {
28 | PackageManager pm = context.getPackageManager();
29 | List packages = pm.getInstalledApplications(0);
30 | for (ApplicationInfo packageInfo : packages) {
31 | if (packageInfo.packageName.equals(targetPackage)) return true;
32 | }
33 | return false;
34 | }
35 | }
--------------------------------------------------------------------------------
/library/src/main/java/hotchemi/android/rate/Utils.java:
--------------------------------------------------------------------------------
1 | package hotchemi.android.rate;
2 |
3 | import android.annotation.SuppressLint;
4 | import android.app.AlertDialog;
5 | import android.content.Context;
6 | import android.os.Build;
7 |
8 | final class Utils {
9 |
10 | private Utils() {
11 | }
12 |
13 | static boolean underHoneyComb() {
14 | return Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB;
15 | }
16 |
17 | static boolean isLollipop() {
18 | return Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP || Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP_MR1;
19 | }
20 |
21 | static int getDialogTheme() {
22 | return isLollipop() ? R.style.CustomLollipopDialogStyle : 0;
23 | }
24 |
25 | @SuppressLint("NewApi")
26 | static AlertDialog.Builder getDialogBuilder(Context context) {
27 | if (underHoneyComb()) {
28 | return new AlertDialog.Builder(context);
29 | } else {
30 | return new AlertDialog.Builder(context, getDialogTheme());
31 | }
32 | }
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/library/src/main/res/values-cs/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Ohodnotit aplikaci
3 | Pokud se Vám aplikace líbí, rádi bychom Vás poprosili o její ohodnocení. Nezabere to více než minutu. Děkujeme za Vaši podporu!
4 | Ohodnotit nyní
5 | Později
6 | Ne, díky
7 |
8 |
--------------------------------------------------------------------------------
/library/src/main/res/values-de/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Bewerte diese App
3 | Falls dir diese App gefällt, könntest du dir bitte einen Moment Zeit nehmen, sie zu bewerten? Es dauert nicht länger als eine Minute. Vielen Dank für deine Unterstützung!
4 | Jetzt bewerten
5 | Später erinnern
6 | Nein, danke
7 |
--------------------------------------------------------------------------------
/library/src/main/res/values-es/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Valorar la aplicación
3 | Si te ha gustado la aplicación, ¿te importaría valorar la aplicación? No te llevará más de un minuto. ¡Gracias por tu apoyo!
4 | Valorar ahora
5 | Recuérdamelo más tarde
6 | ¡No, gracias!
7 |
--------------------------------------------------------------------------------
/library/src/main/res/values-eu/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Puntuatu app hau
3 | App hau gustoko baduzu, tartetxo batean puntuatu nahiko zenuke? Minutu batean baino azkarrago egiten da. Eskerrik asko zure laguntzagatik!
4 | Puntuatu orain
5 | Galdetu geroago
6 | Ez, eskerrik asko
7 |
--------------------------------------------------------------------------------
/library/src/main/res/values-fa/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | به اپ امتياز دهيد
3 | اگر از استفاده اين اپ لذت مي بريد درصورت امكان به ما امتياز دهيد . بيشتر از چند دقيقه زمان نمي برد. ممنون از حمات شما.
4 | الان امتياز مي دهم
5 | بعدا ياد آوري كن
6 | نه ممنون
7 |
8 |
--------------------------------------------------------------------------------
/library/src/main/res/values-fr/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Evaluation de l\'application
3 | Vous aimez notre application, voulez-vous prendre un moment pour l\'évaluer ? Cela ne vous prendra pas plus d\'une minute. Merci de votre soutien !
4 | Évaluer maintenant
5 | Me rappeler plus tard
6 | Non, merci
7 |
8 |
--------------------------------------------------------------------------------
/library/src/main/res/values-it/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Vota quest\'app
3 | Se ti piace usare quest\'app, ti dispiacerebbe trovare un momento per votarla? Non richiede più di un minuto. Grazie per il tuo supporto!
4 | Votala adesso
5 | Ricordamelo più tardi
6 | No, Grazie
7 |
8 |
--------------------------------------------------------------------------------
/library/src/main/res/values-iw/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | דרגו את האפלקציה
3 | אם אתם נהנים מהשימוש באפליקציה, מה דעתכם לדרג אותה? זה לא ייקח יותר מדקה. תודה על התמיכה!
4 | דרגו כעת
5 | אחר כך
6 | לא תודה
7 |
8 |
--------------------------------------------------------------------------------
/library/src/main/res/values-ja/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | アプリの評価
3 | このアプリをお使い頂き大変ありがとうございます。もしよろしければ1分程で済みますので、このアプリの評価をお願いします。ご協力感謝いたします!
4 | 今すぐ評価する
5 | 後でする
6 | いえ、結構です
7 |
--------------------------------------------------------------------------------
/library/src/main/res/values-ko/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | 앱의 평가
3 | 이 응용 프로그램을 사용하셔야 대단히 감사합니다. 만약 괜찮 으시면 1 분 정도로 끝나기 때문에이 응용 프로그램의 평가를 부탁드립니다. 도와 주셔서 감사합니다!
4 | 지금 평가
5 | 나중에하는
6 | 아니, 괜찮아요
7 |
--------------------------------------------------------------------------------
/library/src/main/res/values-pl/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Oceń aplikację
3 | Jeśli podoba Ci ta się aplikacja, to czy poświęcisz chwilę, aby ją ocenić? Nie zajmie Ci to dłużej niż minutę. Dziękujemy za Twoje wsparcie!
4 | Oceń teraz
5 | Przypomnij mi później
6 | Nie, dziękuję
7 |
8 |
--------------------------------------------------------------------------------
/library/src/main/res/values-pt/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Avaliar a aplicação
3 | Gosta da aplicação? Então não se importaria de a avaliar? Não demora mais do que um minuto. Obrigado pelo seu apoio!
4 | Avaliar agora
5 | Mais tarde
6 | Não, Obrigado
7 |
--------------------------------------------------------------------------------
/library/src/main/res/values-ru/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Оцените это приложение
3 | Если вам нравится это приложение не забудьте оценить его в Google Play, это потребует не более минуты вашего времени. Спасибо за вашу поддержку!
4 | Оценить сейчас
5 | Напомнить позже
6 | Нет, спасибо
7 |
--------------------------------------------------------------------------------
/library/src/main/res/values-tr/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Bu uygulamaya puan verin
3 | Eğer bu uygulamayı beğendiyseniz birkaç dakikanızı ayırarak puan verir miydiniz? Bir dakikadan fazla sürmeyecek. Desteğiniz için teşekkür ederiz!
4 | Puan ver
5 | Belki daha sonra
6 | Hayır
7 |
8 |
--------------------------------------------------------------------------------
/library/src/main/res/values-uk/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Оцініть цей додаток
3 | Якщо вам подобається цей додаток - не забудьте оцінити його у Google Play, це займе лише хвилину вашого часу. Дякуємо за вашу підтримку!
4 | Оцінити зараз
5 | Нагадати пізніше
6 | Ні, дякую
7 |
8 |
--------------------------------------------------------------------------------
/library/src/main/res/values-v21/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
9 |
16 |
17 |
25 |
26 |
--------------------------------------------------------------------------------
/library/src/main/res/values-vi/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Đánh giá ứng dụng
3 | Nếu bạn thích ứng dụng này, bạn có thể vui lòng bỏ ra chút ít thời gian để đánh giá nó? Bạn sẽ chỉ mất khoảng 1 phút để thực hiện. Cảm ơn vì đã ủng hộ!
4 | Đánh giá ngay
5 | Nhắc lại sau
6 | Không, cảm ơn
7 |
--------------------------------------------------------------------------------
/library/src/main/res/values-zh/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | 給五顆星評價的鼓勵?
3 | 如果你喜歡這個 App,希望你能給予五顆星的評價,讓更多人下載使用它!
4 | 給五顆星
5 | 稍候提醒我
6 | 不,謝謝
7 |
8 |
--------------------------------------------------------------------------------
/library/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Rate this app
3 | 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!
4 | Rate It Now
5 | Remind Me Later
6 | No, Thanks
7 |
--------------------------------------------------------------------------------
/sample/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/sample/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 23
5 | buildToolsVersion '23.0.2'
6 |
7 | defaultConfig {
8 | minSdkVersion 9
9 | targetSdkVersion 23
10 | versionCode 1
11 | versionName "1.0"
12 | }
13 | buildTypes {
14 | release {
15 | minifyEnabled false
16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
17 | }
18 | }
19 | }
20 |
21 | repositories {
22 | mavenCentral()
23 | }
24 |
25 | dependencies {
26 | compile project(':library')
27 | }
--------------------------------------------------------------------------------
/sample/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
10 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/sample/src/main/java/hotchemi/android/rate/sample/MainActivity.java:
--------------------------------------------------------------------------------
1 | package hotchemi.android.rate.sample;
2 |
3 | import android.app.Activity;
4 | import android.os.Bundle;
5 | import android.util.Log;
6 |
7 | import hotchemi.android.rate.AppRate;
8 | import hotchemi.android.rate.OnClickButtonListener;
9 | import hotchemi.android.rate.StoreType;
10 |
11 | public class MainActivity extends Activity {
12 |
13 | @Override
14 | protected void onCreate(Bundle savedInstanceState) {
15 | super.onCreate(savedInstanceState);
16 | setContentView(R.layout.activity_main);
17 |
18 | AppRate.with(this)
19 | .setStoreType(StoreType.GOOGLEPLAY) //default is Google, other option is Amazon
20 | .setInstallDays(3) // default 10, 0 means install day.
21 | .setLaunchTimes(10) // default 10 times.
22 | .setRemindInterval(2) // default 1 day.
23 | .setShowLaterButton(true) // default true.
24 | .setDebug(true) // default false.
25 | .setCancelable(false) // default false.
26 | .setOnClickButtonListener(new OnClickButtonListener() { // callback listener.
27 | @Override
28 | public void onClickButton(int which) {
29 | Log.d(MainActivity.class.getName(), Integer.toString(which));
30 | }
31 | })
32 | .setTitle(R.string.new_rate_dialog_title)
33 | .setTextLater(R.string.new_rate_dialog_later)
34 | .setTextNever(R.string.new_rate_dialog_never)
35 | .setTextRateNow(R.string.new_rate_dialog_ok)
36 | .monitor();
37 |
38 | AppRate.showRateDialogIfMeetsConditions(this);
39 | }
40 |
41 | }
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hotchemi/Android-Rate/5d327976fd5106b8edfee5e5f7ad05dfe66c7857/sample/src/main/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hotchemi/Android-Rate/5d327976fd5106b8edfee5e5f7ad05dfe66c7857/sample/src/main/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hotchemi/Android-Rate/5d327976fd5106b8edfee5e5f7ad05dfe66c7857/sample/src/main/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/src/main/res/drawable-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hotchemi/Android-Rate/5d327976fd5106b8edfee5e5f7ad05dfe66c7857/sample/src/main/res/drawable-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
11 |
12 |
--------------------------------------------------------------------------------
/sample/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/sample/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 |
6 |
7 |
--------------------------------------------------------------------------------
/sample/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Android-Rate Sample
5 | Hello world!
6 |
7 | Rate Me!
8 | Never
9 | Later
10 | Rate
11 |
12 |
13 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':library', ':sample'
--------------------------------------------------------------------------------