Skip to content

Commit

Permalink
Apptentive Android SDK 5.8.0 (#234)
Browse files Browse the repository at this point in the history
  • Loading branch information
PoornimaApptentive authored Jan 6, 2022
1 parent 74d3028 commit ebaaa32
Show file tree
Hide file tree
Showing 27 changed files with 357 additions and 108 deletions.
2 changes: 1 addition & 1 deletion .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
@@ -1 +1 @@
* @frankus @twinklesharma1311
* @twinklesharma1311 @ChaseApptentive @PoornimaApptentive
12 changes: 0 additions & 12 deletions .idea/runConfigurations.xml

This file was deleted.

19 changes: 17 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,24 @@
# 2022-01-06 - v5.8.0

#### Major changes

* Add safeguard parameter for interaction frequency of Rating Dialog.

#### Fixes

* Fix a couple of possible ANR issues.

#### Improvements

* Update License & README files.

# 2021-08-26 - v5.7.1

#### Fixes

* Fix a couple of issues related to Android 12
* Fix Navigate to Link interaction for API 30+
* Fix a couple of issues related to Android 12.
* Fix Navigate to Link interaction for API 30+.
* Remove all references to AdvertiserId.

# 2021-08-04 - v5.7.0

Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

We love contributions!

Any contributions to the master apptentive-ios project must sign the [Individual Contributor License Agreement (CLA)](https://docs.google.com/a/apptentive.com/spreadsheet/viewform?formkey=dDhMaXJKQnRoX0dRMzZNYnp5bk1Sbmc6MQ#gid=0). It's a doc that makes our lawyers happy and ensures we can provide a solid open source project.
Any contributions to the master apptentive-android project must sign the [Individual Contributor License Agreement (CLA)](https://docs.google.com/a/apptentive.com/spreadsheet/viewform?formkey=dDhMaXJKQnRoX0dRMzZNYnp5bk1Sbmc6MQ#gid=0). It's a doc that makes our lawyers happy and ensures we can provide a solid open source project.

When you want to submit a change, send us a [pull request](https://github.com/apptentive/apptentive-android/pulls). Before we merge, we'll check to make sure you're on the list of people who've signed our CLA.

Expand Down
2 changes: 1 addition & 1 deletion License.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Copyright (c) 2011-2019, Apptentive, Inc.
Copyright (c) 2011-2021, Apptentive, Inc.
All rights reserved.

Redistribution and use in source and binary forms, with or without
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ use your app, to talk to them at the right time, and in the right way.

#### [Android Interface Customization](https://learn.apptentive.com/knowledge-base/android-interface-customization/)

#### [Apptentive SDK API Javadoc](http://www.apptentive.com/docs/android/api)
#### [Apptentive SDK API Javadoc](https://learn.apptentive.com/docs/android/api/index.html)

##### [API Changes here](docs/APIChanges.md)

##### [Release Notes](https://learn.apptentive.com/knowledge-base/android-sdk-release-notes/)

##### Binary releases are hosted for Maven [here](http://search.maven.org/#artifactdetails|com.apptentive|apptentive-android|5.7.1|aar)
##### Binary releases are hosted for Maven [here](http://search.maven.org/#artifactdetails|com.apptentive|apptentive-android|5.8.0|aar)

#### Reporting Bugs

Expand Down
44 changes: 19 additions & 25 deletions apptentive/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,36 +3,30 @@ init()
apply plugin: 'com.android.library'

dependencies {
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'androidx.cardview:cardview:1.0.0'
implementation 'com.google.android.material:material:1.2.0'
implementation "androidx.appcompat:appcompat:$appcompat_library_version"
implementation "androidx.legacy:legacy-support-v4:$legacy_support_v4_version"
implementation "com.google.android.material:material:$material_design_version"
implementation "com.google.android.play:core:$play_core_version"
implementation "com.google.android.gms:play-services-base:$play_services_base_version"

// Play Core library required for in-app review flow
implementation 'com.google.android.play:core:1.8.0'
testImplementation "junit:junit:$junit_version"
testImplementation "org.powermock:powermock-module-junit4:$powermock_version"
testImplementation "org.powermock:powermock-module-junit4-rule:$powermock_version"
testImplementation "org.powermock:powermock-api-mockito2:$powermock_version"
testImplementation "org.powermock:powermock-classloading-xstream:$powermock_version"

// Play Services library required to check for GPS availability before showing in-app review
implementation 'com.google.android.gms:play-services-base:17.4.0'

testImplementation 'junit:junit:4.13'
testImplementation 'org.powermock:powermock-module-junit4:1.6.6'
testImplementation 'org.powermock:powermock-module-junit4-rule:1.6.6'
testImplementation 'org.powermock:powermock-api-mockito:1.6.6'
testImplementation 'org.powermock:powermock-classloading-xstream:1.6.6'

// Required for instrumented tests
androidTestImplementation 'androidx.annotation:annotation:1.1.0'
androidTestImplementation 'androidx.test:runner:1.3.0'
androidTestImplementation 'androidx.test:rules:1.3.0'
androidTestImplementation "androidx.annotation:annotation:$annotation_version"
androidTestImplementation "androidx.test:runner:$androidx_test_version"
androidTestImplementation "androidx.test:rules:$androidx_test_version"
}

android {
compileSdkVersion 30
buildToolsVersion '30.0.2'
compileSdkVersion rootProject.compileSdkVersion
buildToolsVersion rootProject.buildToolsVersion

defaultConfig {
minSdkVersion 14
targetSdkVersion 30
minSdkVersion rootProject.minSdkVersion
targetSdkVersion rootProject.targetSdkVersion
// BUILD_NUMBER is provided by Jenkins. Default to 1 in dev builds.
versionCode System.getenv("BUILD_NUMBER") as Integer ?: System.getenv("TRAVIS_BUILD_NUMBER") as Integer ?: 1
versionName project.version
Expand All @@ -56,8 +50,8 @@ android {
}

compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}

testOptions {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {

@Override
protected void onDestroy() {
super.onDestroy();
unregisterNotification();
super.onDestroy();
}

//endregion
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
import com.apptentive.android.sdk.module.engagement.interaction.model.TermsAndConditions;
import com.apptentive.android.sdk.util.StringUtils;

import java.util.concurrent.TimeUnit;

public class ApptentiveConfiguration {
private final String apptentiveKey;
private final String apptentiveSignature;
Expand All @@ -23,6 +25,7 @@ public class ApptentiveConfiguration {
private Encryption encryption;
private boolean shouldCollectAndroidIdOnPreOreoTargets;
private TermsAndConditions surveyTermsAndConditions;
private Long interactionThrottle;

public ApptentiveConfiguration(@NonNull String apptentiveKey, @NonNull String apptentiveSignature) {
if (StringUtils.isNullOrEmpty(apptentiveKey)) {
Expand Down Expand Up @@ -150,4 +153,22 @@ public TermsAndConditions getSurveyTermsAndConditions() {
public void setSurveyTermsAndConditions(TermsAndConditions surveyTermsAndConditions) {
this.surveyTermsAndConditions = surveyTermsAndConditions;
}

public Long getInteractionThrottle() {
return interactionThrottle != null ? interactionThrottle : TimeUnit.DAYS.toMillis(7);
}

/**
* Sets a time limit throttle which determines when a rating interaction can be shown again.
* Default is 7 days.
*
* @see TimeUnit for conversion utils
* e.g. TimeUnit.MINUTES.toMillis(10); or TimeUnit.DAYS.toMillis(30);
*
* @param interactionThrottle The length of time (in milliseconds) to wait before showing
* the same interaction again.
*/
public void setRatingInteractionThrottle(Long interactionThrottle) {
this.interactionThrottle = interactionThrottle;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,14 @@
import com.apptentive.android.sdk.conversation.Conversation;
import com.apptentive.android.sdk.conversation.ConversationProxy;
import com.apptentive.android.sdk.module.engagement.interaction.InteractionManager;
import com.apptentive.android.sdk.module.engagement.interaction.model.Interaction;
import com.apptentive.android.sdk.module.engagement.interaction.model.TermsAndConditions;
import com.apptentive.android.sdk.module.rating.IRatingProvider;
import com.apptentive.android.sdk.module.survey.OnSurveyFinishedListener;
import com.apptentive.android.sdk.storage.AppRelease;
import com.apptentive.android.sdk.storage.ApptentiveTaskManager;
import com.apptentive.android.sdk.util.Nullsafe;
import com.apptentive.android.sdk.util.ThrottleUtils;

import java.util.Map;

Expand Down Expand Up @@ -73,4 +75,5 @@ public interface ApptentiveInstance extends Nullsafe {
String getDefaultAppDisplayName();

TermsAndConditions getSurveyTermsAndConditions();
boolean shouldThrottleInteraction(Interaction.Type interactionType);
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import com.apptentive.android.sdk.model.LogoutPayload;
import com.apptentive.android.sdk.module.engagement.EngagementModule;
import com.apptentive.android.sdk.module.engagement.interaction.InteractionManager;
import com.apptentive.android.sdk.module.engagement.interaction.model.Interaction;
import com.apptentive.android.sdk.module.engagement.interaction.model.MessageCenterInteraction;
import com.apptentive.android.sdk.module.engagement.interaction.model.TermsAndConditions;
import com.apptentive.android.sdk.module.messagecenter.MessageManager;
Expand Down Expand Up @@ -118,6 +119,8 @@ public class ApptentiveInternal implements ApptentiveInstance, ApptentiveNotific
// Used for temporarily holding customData that needs to be sent on the next message the consumer sends.
private Map<String, Object> customData;

private ThrottleUtils throttleUtils;

private static final String PUSH_ACTION = "action";
private static final String PUSH_CONVERSATION_ID = "conversation_id";
private static final int LOG_HISTORY_SIZE = 2;
Expand Down Expand Up @@ -176,6 +179,7 @@ private ApptentiveInternal(Application application, ApptentiveConfiguration conf
globalSharedPrefs = application.getSharedPreferences(Constants.PREF_NAME, Context.MODE_PRIVATE);
apptentiveHttpClient = new ApptentiveHttpClient(apptentiveKey, apptentiveSignature, getEndpointBase(globalSharedPrefs));

this.throttleUtils = new ThrottleUtils(configuration.getInteractionThrottle(), getGlobalSharedPrefs());
DeviceManager deviceManager = new DeviceManager(androidID);
conversationManager = new ConversationManager(appContext, Util.getInternalDir(appContext, CONVERSATIONS_DIR, true), encryption, deviceManager);

Expand Down Expand Up @@ -222,28 +226,28 @@ static void createInstance(@NonNull Application application, @NonNull Apptentive
// set log level before we initialize log monitor since log monitor can override it as well
ApptentiveLog.overrideLogLevel(configuration.getLogLevel());

// troubleshooting mode
if (configuration.isTroubleshootingModeEnabled()) {
// initialize log writer
ApptentiveLog.initializeLogWriter(application.getApplicationContext(), LOG_HISTORY_SIZE);

// try initializing log monitor
LogMonitor.startSession(application.getApplicationContext(), apptentiveKey, apptentiveSignature);
} else {
ApptentiveLog.i(TROUBLESHOOT, "Troubleshooting is disabled in the app configuration");
}

synchronized (ApptentiveInternal.class) {
if (sApptentiveInternal == null) {
ApptentiveLog.i("Registering Apptentive Android SDK %s", Constants.getApptentiveSdkVersion());
ApptentiveLog.v("ApptentiveKey=%s ApptentiveSignature=%s", apptentiveKey, apptentiveSignature);
// resolve Android ID
boolean shouldGenerateRandomAndroidID = Build.VERSION.SDK_INT < Build.VERSION_CODES.O && !configuration.shouldCollectAndroidIdOnPreOreoTargets();
String androidID = resolveAndroidID(application.getApplicationContext(), shouldGenerateRandomAndroidID);
sApptentiveInternal = new ApptentiveInternal(application, configuration, androidID);
dispatchOnConversationQueue(new DispatchTask() {
@Override
protected void execute() {
// troubleshooting mode
if (configuration.isTroubleshootingModeEnabled()) {
// initialize log writer
ApptentiveLog.initializeLogWriter(application.getApplicationContext(), LOG_HISTORY_SIZE);

// try initializing log monitor
LogMonitor.startSession(application.getApplicationContext(), apptentiveKey, apptentiveSignature);
} else {
ApptentiveLog.i(TROUBLESHOOT, "Troubleshooting is disabled in the app configuration");
}

sApptentiveInternal = new ApptentiveInternal(application, configuration, androidID);
sApptentiveInternal.start();
}
});
Expand Down Expand Up @@ -398,6 +402,11 @@ public TermsAndConditions getSurveyTermsAndConditions() {
return surveyTermsAndConditions;
}

@Override
public boolean shouldThrottleInteraction(Interaction.Type interactionType) {
return throttleUtils.shouldThrottleInteraction(interactionType);
}

public boolean isApptentiveDebuggable() {
return appRelease.isDebug();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,13 @@
import com.apptentive.android.sdk.conversation.ConversationProxy;
import com.apptentive.android.sdk.debug.Assert;
import com.apptentive.android.sdk.module.engagement.interaction.InteractionManager;
import com.apptentive.android.sdk.module.engagement.interaction.model.Interaction;
import com.apptentive.android.sdk.module.engagement.interaction.model.TermsAndConditions;
import com.apptentive.android.sdk.module.rating.IRatingProvider;
import com.apptentive.android.sdk.module.survey.OnSurveyFinishedListener;
import com.apptentive.android.sdk.storage.AppRelease;
import com.apptentive.android.sdk.storage.ApptentiveTaskManager;
import com.apptentive.android.sdk.util.ThrottleUtils;

import java.util.Map;

Expand Down Expand Up @@ -216,6 +218,11 @@ public TermsAndConditions getSurveyTermsAndConditions() {
return null;
}

@Override
public boolean shouldThrottleInteraction(Interaction.Type interactionType) {
return false;
}

private void failMethodCall(String method) {
Assert.assertFail("Unable to invoke '%s': Apptentive SDK is not properly initialized", method);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,11 @@ public class Conversation implements DataChangedListener, Destroyable, DeviceDat
@Override
protected void execute() {
try {
if (ApptentiveLog.canLog(ApptentiveLog.Level.VERBOSE)) {
ApptentiveLog.v(CONVERSATION, "Saving conversation data...");
ApptentiveLog.v(CONVERSATION, "EventData: %s", getEventData().toString());
ApptentiveLog.v(CONVERSATION, "Messages: %s", messageManager.getMessageStore().toString());
}
saveConversationData();
} catch (Exception e) {
ApptentiveLog.e(CONVERSATION, e, "Exception while saving conversation data");
Expand Down Expand Up @@ -401,11 +406,6 @@ public void scheduleSaveConversationData() {
* if succeed.
*/
private synchronized void saveConversationData() throws SerializerException {
if (ApptentiveLog.canLog(ApptentiveLog.Level.VERBOSE)) {
ApptentiveLog.v(CONVERSATION, "Saving conversation data...");
ApptentiveLog.v(CONVERSATION, "EventData: %s", getEventData().toString());
ApptentiveLog.v(CONVERSATION, "Messages: %s", messageManager.getMessageStore().toString());
}
long start = System.currentTimeMillis();

FileSerializer serializer = new EncryptedFileSerializer(conversationDataFile, encryption);
Expand Down Expand Up @@ -438,7 +438,7 @@ boolean migrateConversationData() throws SerializerException {
return false;
}

void loadConversationData() throws SerializerException {
synchronized void loadConversationData() throws SerializerException {
long start = System.currentTimeMillis();

FileSerializer serializer = new EncryptedFileSerializer(conversationDataFile, encryption);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import com.apptentive.android.sdk.model.ExtendedData;
import com.apptentive.android.sdk.module.engagement.interaction.model.Interaction;
import com.apptentive.android.sdk.module.engagement.interaction.model.MessageCenterInteraction;
import com.apptentive.android.sdk.util.ThrottleUtils;
import com.apptentive.android.sdk.util.Util;
import com.apptentive.android.sdk.util.threading.DispatchTask;

Expand Down Expand Up @@ -90,7 +91,11 @@ private static boolean doEngage(Conversation conversation, Context context, Stri

Interaction interaction = conversation.getApplicableInteraction(eventLabel, true);
if (interaction != null) {
return launchInteraction(context, conversation, interaction);
if (!ApptentiveInternal.getInstance().shouldThrottleInteraction(interaction.getType())) {
return launchInteraction(context, conversation, interaction);
} else {
return false;
}
}
ApptentiveLog.d(INTERACTIONS, "No interaction to show for event: '%s'", eventLabel);
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,8 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) {

@Override
public void onPause() {
super.onPause();
transit();
super.onPause();
}

@Override
Expand Down
Loading

0 comments on commit ebaaa32

Please sign in to comment.