diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..8134017 --- /dev/null +++ b/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2015 SurveyMonkey + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/README.md b/README.md new file mode 100644 index 0000000..67b1ad2 --- /dev/null +++ b/README.md @@ -0,0 +1,75 @@ +## SurveyMonkey Feedback SDK for Android + +The SurveyMonkey Feedback SDK for Android allows app developers to integrate SurveyMonkey surveys and respondent data into their apps. Checkout our [documentation site](http://surveymonkey.github.io/surveymonkey-android-sdk/) for more information. + +We strive to fix bugs and add new features as quickly as possible. Please watch our Github repo to stay up to date. + +To download the SDK, either clone the SDK +```bash +git clone https://github.com/SurveyMonkey/surveymonkey-android-sdk.git +``` +Or download the [latest release](https://github.com/SurveyMonkey/surveymonkey-android-sdk/releases) + +### Setting up your SDK Collector + +To use the SurveyMonkey Feedback SDK, you must first create a survey on [ SurveyMonkey.com](https://www.surveymonkey.com). + +1. Once you have created your SurveyMonkey survey, navigate to the **Collect** tab and select **+ New Collector > SDK** from the menu on the righthand side. +2. Click **Generate** - The code you generate is your **Survey Hash**, you'll use this to point the SDK to your survey in the steps below. +### Integrating with Android Studio + +1. From the menu bar, click **File -> New Module -> Import .JAR or .AAR package** +2. Navigate to the **surveymonkeyandroidsdk** directory that is contained in the **surveymonkeyandroidsdk** repo +3. Select the **surveymonkey-android-sdk.aar** file and click Finish +4. In your **AndroidManifest.xml** file, make sure you've included the `` permission +5. Make sure your **build.gradle** file has `compile project(':surveymonkey_android_sdk')` under `dependencies {}` + +That's it! + +###Integrating the SurveyMonkey SDK with your app +For a detailed example, take a look at the **SimpleActivity** sample project in our Github repo + + +#### Important +The SurveyMonkey Feedback SDK makes use of the `startActivityForResult(Intent, int)` method lifecycle - thus, if you want to consume the respondent data returned by our SDK, you'll need to implement `onActivityResult()` in whichever activity you present surveys from. + +The survey respondent data is returned as JSON. To parse it, implement the following in your `onActivityResult()`: +```java +String respondent = intent.getStringExtra("smRespondent"); +JSONObject surveyResponse = new JSONObject(respondent); +``` + +If `resultCode != RESULT_OK` in your `onActivityResult`, an error has occurred. To obtain and parse the error into an SMError object, call: +```java +SMError e = (SMError) intent.getSerializableExtra(SM_ERROR); +``` + +#### Getting Started +1. `import com.surveymonkey.surveymonkeyandroidsdk.SurveyMonkey;` and (for error handling) +`import com.surveymonkey.surveymonkeyandroidsdk.utils.SMError;` +2. Initialize the SDK like so: `private SurveyMonkey sdkInstance = new SurveyMonkey();` + +#### The Intercept Modal +To kick off the SurveyMonkey Feedback SDK Intercept process, call: +```java +sdkInstance.onStart(this, [SAMPLE_APP_NAME], [SAMPLE_REQUEST_CODE], [SAMPLE_SURVEY_HASH]); +``` +from your main activity. This will check to see if the user should be prompted to take your survey (i.e. `if (timeSinceLastSurveyPrompt > maxTimeIntervalBetweenSurveyPrompts)`). The copy of the prompts, as well as the time intervals, can be customized, see our docs for more information. + +If you are a **Platinum** user and want to include custom variables with each survey response, create a flat JSONObject with your custom variables and use: +```java +sdkInstance.onStart(this, [SAMPLE_APP_NAME], [SAMPLE_REQUEST_CODE], [SAMPLE_SURVEY_HASH], [SAMPLE_CUSTOM_VARIABLES_DICTIONARY]); +``` + +#### Presenting a Survey to the User +To present a survey for the user to take, call +```java +sdkInstance.startSMFeedbackActivityForResult(this, [SAMPLE_REQUEST_CODE], [SAMPLE_SURVEY_HASH]); +``` +Again, if you are a **Platinum** user and want to include custom variables with each survey response, create a flat JSONObject with your custom variables and use: +```java +sdkInstance.startSMFeedbackActivityForResult(this, [SAMPLE_REQUEST_CODE], [SAMPLE_SURVEY_HASH], [SAMPLE_CUSTOM_VARIABLES_DICTIONARY]); +``` + +####Issues and Bugs +Please submit any issues with the SDK to us via Github issues. diff --git a/SimpleSurvey/.idea/.name b/SimpleSurvey/.idea/.name new file mode 100644 index 0000000..f318fe7 --- /dev/null +++ b/SimpleSurvey/.idea/.name @@ -0,0 +1 @@ +Simple Survey \ No newline at end of file diff --git a/SimpleSurvey/.idea/compiler.xml b/SimpleSurvey/.idea/compiler.xml new file mode 100644 index 0000000..1f2af51 --- /dev/null +++ b/SimpleSurvey/.idea/compiler.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SimpleSurvey/.idea/copyright/profiles_settings.xml b/SimpleSurvey/.idea/copyright/profiles_settings.xml new file mode 100644 index 0000000..e7bedf3 --- /dev/null +++ b/SimpleSurvey/.idea/copyright/profiles_settings.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/SimpleSurvey/.idea/gradle.xml b/SimpleSurvey/.idea/gradle.xml new file mode 100644 index 0000000..1ee1678 --- /dev/null +++ b/SimpleSurvey/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + \ No newline at end of file diff --git a/SimpleSurvey/.idea/misc.xml b/SimpleSurvey/.idea/misc.xml new file mode 100644 index 0000000..9cf0544 --- /dev/null +++ b/SimpleSurvey/.idea/misc.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + Android Lint + + + Control flow issues + + + Naming conventions + + + XML + + + + + ClassNamePrefixedWithPackageName + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SimpleSurvey/.idea/modules.xml b/SimpleSurvey/.idea/modules.xml new file mode 100644 index 0000000..c906465 --- /dev/null +++ b/SimpleSurvey/.idea/modules.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/SimpleSurvey/.idea/runConfigurations.xml b/SimpleSurvey/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/SimpleSurvey/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/SimpleSurvey/.idea/vcs.xml b/SimpleSurvey/.idea/vcs.xml new file mode 100644 index 0000000..6564d52 --- /dev/null +++ b/SimpleSurvey/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/SimpleSurvey/app/build.gradle b/SimpleSurvey/app/build.gradle new file mode 100644 index 0000000..95ac53d --- /dev/null +++ b/SimpleSurvey/app/build.gradle @@ -0,0 +1,27 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 23 + buildToolsVersion "23.0.2" + + defaultConfig { + applicationId "com.surveymonkey.simplesurvey" + minSdkVersion 9 + targetSdkVersion 23 + versionCode 1 + versionName "1.0" + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } +} + +dependencies { + compile fileTree(dir: 'libs', include: ['*.jar']) + testCompile 'junit:junit:4.12' + compile 'com.android.support:appcompat-v7:23.1.1' + compile project(':surveymonkey_android_sdk') +} diff --git a/SimpleSurvey/app/proguard-rules.pro b/SimpleSurvey/app/proguard-rules.pro new file mode 100644 index 0000000..90f452f --- /dev/null +++ b/SimpleSurvey/app/proguard-rules.pro @@ -0,0 +1,17 @@ +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in /Users/benl/sdk/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the proguardFiles +# directive in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} diff --git a/SimpleSurvey/app/src/androidTest/java/com/surveymonkey/simplesurvey/ApplicationTest.java b/SimpleSurvey/app/src/androidTest/java/com/surveymonkey/simplesurvey/ApplicationTest.java new file mode 100644 index 0000000..563a96f --- /dev/null +++ b/SimpleSurvey/app/src/androidTest/java/com/surveymonkey/simplesurvey/ApplicationTest.java @@ -0,0 +1,13 @@ +package com.surveymonkey.simplesurvey; + +import android.app.Application; +import android.test.ApplicationTestCase; + +/** + * Testing Fundamentals + */ +public class ApplicationTest extends ApplicationTestCase { + public ApplicationTest() { + super(Application.class); + } +} \ No newline at end of file diff --git a/SimpleSurvey/app/src/main/AndroidManifest.xml b/SimpleSurvey/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..2c6e001 --- /dev/null +++ b/SimpleSurvey/app/src/main/AndroidManifest.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + diff --git a/SimpleSurvey/app/src/main/java/com/surveymonkey/simplesurvey/SimpleActivity.java b/SimpleSurvey/app/src/main/java/com/surveymonkey/simplesurvey/SimpleActivity.java new file mode 100644 index 0000000..f0472d1 --- /dev/null +++ b/SimpleSurvey/app/src/main/java/com/surveymonkey/simplesurvey/SimpleActivity.java @@ -0,0 +1,111 @@ +package com.surveymonkey.simplesurvey; + +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; +import android.util.Log; +import android.view.View; +import android.widget.Toast; + +import com.surveymonkey.surveymonkeyandroidsdk.SurveyMonkey; +import com.surveymonkey.surveymonkeyandroidsdk.utils.SMError; +import com.surveymonkey.surveymonkeyandroidsdkexample.R; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +public class SimpleActivity extends Activity { + + public static final int SM_REQUEST_CODE = 0; + public static final String SM_RESPONDENT = "smRespondent"; + public static final String SM_ERROR = "smError"; + public static final String RESPONSES = "responses"; + public static final String QUESTION_ID = "question_id"; + public static final String FEEDBACK_QUESTION_ID = "813797519"; + public static final String ANSWERS = "answers"; + public static final String ROW_ID = "row_id"; + public static final String FEEDBACK_FIVE_STARS_ROW_ID = "9082377273"; + public static final String FEEDBACK_POSITIVE_ROW_ID_2 = "9082377274"; + public static final String SAMPLE_APP = "Sample App"; + public static final String SURVEY_HASH = "LBQK27G"; + // Initialize the SurveyMonkey SDK like so + private SurveyMonkey s = new SurveyMonkey(); + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.main); + //Here we're setting up the SurveyMonkey Intercept Dialog -- the user will be prompted to take the survey 3 days after app install. + // Once prompted, the user will be reminded to take the survey again in 3 weeks if they decline or 3 months if they consent to take the survey. + // The onStart method can be overloaded so that you can supply your own prompts and intervals -- for more information, see our documentation on Github. + s.onStart(this, SAMPLE_APP, SM_REQUEST_CODE, SURVEY_HASH); + } + + @Override + protected void onStart() { + super.onStart(); + + } + + public void takeSurvey(View view) { + //This is how you display a survey for the user to take + // Remember: you must supply the parent activity (e.g. this), your own request code (to differentiate from other activities), and the collector hash of the SDK collector you've created at SurveyMonkey.com + s.startSMFeedbackActivityForResult(this, SM_REQUEST_CODE, SURVEY_HASH); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent intent) { + //This is where you consume the respondent data returned by the SurveyMonkey Mobile Feedback SDK + //In this example, we deserialize the user's response, check to see if they gave our app 4 or 5 stars, and then provide visual prompts to the user based on their response + super.onActivityResult(requestCode, resultCode, intent); + if (resultCode == RESULT_OK) { + boolean isPromoter = false; + try { + String respondent = intent.getStringExtra(SM_RESPONDENT); + Log.d("SM", respondent); + JSONObject surveyResponse = new JSONObject(respondent); + JSONArray responsesList = surveyResponse.getJSONArray(RESPONSES); + JSONObject response; + JSONArray answers; + JSONObject currentAnswer; + for (int i = 0; i < responsesList.length(); i++) { + response = responsesList.getJSONObject(i); + if (response.getString(QUESTION_ID).equals(FEEDBACK_QUESTION_ID)) { + answers = response.getJSONArray(ANSWERS); + for (int j = 0; j < answers.length(); j++) { + currentAnswer = answers.getJSONObject(j); + if (currentAnswer.getString(ROW_ID).equals(FEEDBACK_FIVE_STARS_ROW_ID) || currentAnswer.getString(ROW_ID).equals(FEEDBACK_POSITIVE_ROW_ID_2)) { + isPromoter = true; + break; + } + } + if (isPromoter) { + break; + } + } + } + } catch (JSONException e) { + Log.getStackTraceString(e); + } + if (isPromoter) { + Toast t = Toast.makeText(this, getString(R.string.promoter_prompt), Toast.LENGTH_LONG); + t.show(); + } else { + Toast t = Toast.makeText(this, getString(R.string.detractor_prompt), Toast.LENGTH_LONG); + t.show(); + } + } else { + Toast t = Toast.makeText(this, getString(R.string.error_prompt), Toast.LENGTH_LONG); + t.show(); + SMError e = (SMError) intent.getSerializableExtra(SM_ERROR); + Log.d("SM-ERROR", e.getDescription()); + } + } + + + @Override + protected void onStop() { + super.onStop(); + } +} diff --git a/SimpleSurvey/app/src/main/res/layout/main.xml b/SimpleSurvey/app/src/main/res/layout/main.xml new file mode 100644 index 0000000..8ddf601 --- /dev/null +++ b/SimpleSurvey/app/src/main/res/layout/main.xml @@ -0,0 +1,17 @@ + + + + +