From 0d985b513f81f99230b7a8bc5da0db7a86196078 Mon Sep 17 00:00:00 2001 From: skykelsey Date: Thu, 28 Apr 2016 17:29:03 -0700 Subject: [PATCH 01/12] Upgrade to Android Studio 2.1.0, upgrade dependencies to latest, stop using gradle.properties for SDK version info, since Android Studio can't resolve from it. --- apptentive/build.gradle | 16 ++++++++-------- build.gradle | 6 +----- gradle.properties | 4 ---- gradle/wrapper/gradle-wrapper.properties | 2 +- samples/apptentive-example/build.gradle | 21 +++++++++++---------- 5 files changed, 21 insertions(+), 28 deletions(-) delete mode 100644 gradle.properties diff --git a/apptentive/build.gradle b/apptentive/build.gradle index 72bac14bc..a3f7057db 100644 --- a/apptentive/build.gradle +++ b/apptentive/build.gradle @@ -7,19 +7,19 @@ repositories { } dependencies { - compile 'com.android.support:support-v4:23.2.1' - compile 'com.android.support:appcompat-v7:23.2.1' - compile 'com.android.support:cardview-v7:23.2.1' - compile 'com.android.support:design:23.2.1' + compile 'com.android.support:support-v4:23.3.0' + compile 'com.android.support:appcompat-v7:23.3.0' + compile 'com.android.support:cardview-v7:23.3.0' + compile 'com.android.support:design:23.3.0' } android { - compileSdkVersion Integer.parseInt(project.ANDROID_BUILD_SDK_VERSION) - buildToolsVersion project.ANDROID_BUILD_TOOLS_VERSION + compileSdkVersion 23 + buildToolsVersion '23.0.3' defaultConfig { - minSdkVersion Integer.parseInt(project.ANDROID_BUILD_MIN_SDK_VERSION) - targetSdkVersion Integer.parseInt(project.ANDROID_BUILD_TARGET_SDK_VERSION) + minSdkVersion 14 + targetSdkVersion 23 // BUILD_NUMBER is provided by Jenkins. Default to 1 in dev builds. versionCode System.getenv("BUILD_NUMBER") as Integer ?: 1 versionName project.version diff --git a/build.gradle b/build.gradle index 25b1589e0..9287dcb7a 100644 --- a/build.gradle +++ b/build.gradle @@ -3,10 +3,6 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:1.5.0' + classpath 'com.android.tools.build:gradle:2.1.0' } -} - -task wrapper(type: Wrapper) { - gradleVersion = '2.6' } \ No newline at end of file diff --git a/gradle.properties b/gradle.properties deleted file mode 100644 index ca9feb444..000000000 --- a/gradle.properties +++ /dev/null @@ -1,4 +0,0 @@ -ANDROID_BUILD_MIN_SDK_VERSION=14 -ANDROID_BUILD_TARGET_SDK_VERSION=23 -ANDROID_BUILD_TOOLS_VERSION=23.0.3 -ANDROID_BUILD_SDK_VERSION=23 \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 8a6c75ea0..10224a558 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.6-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip diff --git a/samples/apptentive-example/build.gradle b/samples/apptentive-example/build.gradle index 1396de426..d064ff50c 100644 --- a/samples/apptentive-example/build.gradle +++ b/samples/apptentive-example/build.gradle @@ -3,12 +3,11 @@ buildscript { jcenter() } dependencies { - classpath 'com.google.gms:google-services:1.5.0' + classpath 'com.google.gms:google-services:2.1.0' } } apply plugin: 'com.android.application' -apply plugin: 'com.google.gms.google-services' repositories { jcenter() @@ -16,19 +15,19 @@ repositories { dependencies { compile project(':apptentive') - compile 'com.android.support:support-v4:23.2.1' - compile 'com.android.support:appcompat-v7:23.2.1' - compile 'com.android.support:cardview-v7:23.2.1' - compile 'com.google.android.gms:play-services-gcm:8.3.0' + compile 'com.android.support:support-v4:23.3.0' + compile 'com.android.support:appcompat-v7:23.3.0' + compile 'com.android.support:cardview-v7:23.3.0' + compile 'com.google.android.gms:play-services-gcm:8.4.0' } android { - compileSdkVersion Integer.parseInt(project.ANDROID_BUILD_SDK_VERSION) - buildToolsVersion project.ANDROID_BUILD_TOOLS_VERSION + compileSdkVersion 23 + buildToolsVersion '23.0.3' defaultConfig { - minSdkVersion Integer.parseInt(project.ANDROID_BUILD_MIN_SDK_VERSION) - targetSdkVersion Integer.parseInt(project.ANDROID_BUILD_TARGET_SDK_VERSION) + minSdkVersion 14 + targetSdkVersion 23 versionCode 1 versionName "1.0" multiDexEnabled true @@ -38,3 +37,5 @@ android { abortOnError false } } + +apply plugin: 'com.google.gms.google-services' From 1e2ade0c0b18d856b09ca97293a2f7e66407440c Mon Sep 17 00:00:00 2001 From: Barry Li Date: Tue, 3 May 2016 14:17:29 -0700 Subject: [PATCH 02/12] ANDROID-647 Enable contextual ActionBar (such as highlighting text for copy/paste) in Message Center and Survey --- .../view/holder/OutgoingCompoundMessageHolder.java | 8 +++----- .../src/main/res/layout/apptentive_message_auto.xml | 4 ++-- .../src/main/res/layout/apptentive_message_incoming.xml | 4 ++-- .../src/main/res/layout/apptentive_message_outgoing.xml | 4 ++-- .../main/res/layout/apptentive_survey_question_base.xml | 1 + apptentive/src/main/res/values/themes.xml | 4 ++-- 6 files changed, 12 insertions(+), 13 deletions(-) diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/module/messagecenter/view/holder/OutgoingCompoundMessageHolder.java b/apptentive/src/main/java/com/apptentive/android/sdk/module/messagecenter/view/holder/OutgoingCompoundMessageHolder.java index 22ce9ca06..a74bd325b 100644 --- a/apptentive/src/main/java/com/apptentive/android/sdk/module/messagecenter/view/holder/OutgoingCompoundMessageHolder.java +++ b/apptentive/src/main/java/com/apptentive/android/sdk/module/messagecenter/view/holder/OutgoingCompoundMessageHolder.java @@ -19,9 +19,7 @@ import java.util.ArrayList; import java.util.List; -/** - * @author Barry Li - */ + public class OutgoingCompoundMessageHolder extends MessageHolder { public ApptentiveMaterialIndeterminateProgressBar progressBar; public TextView messageBodyView; @@ -31,7 +29,7 @@ public OutgoingCompoundMessageHolder(CompoundMessageView view) { super(view); progressBar = (ApptentiveMaterialIndeterminateProgressBar) view.findViewById(R.id.progressBar); messageBodyView = (TextView) view.findViewById(R.id.apptentive_compound_message_body); - imageBandView =(ApptentiveImageGridView) view.findViewById(R.id.grid); + imageBandView = (ApptentiveImageGridView) view.findViewById(R.id.grid); } public void updateMessage(String datestamp, String status, int statusColor, @@ -62,7 +60,7 @@ public void run() { imageBandView.setVisibility(View.VISIBLE); imageBandView.setAdapterItemSize(viewWidth, desiredColumn); List images = new ArrayList(); - for (StoredFile file: imagesToAttach) { + for (StoredFile file : imagesToAttach) { images.add(new ImageItem(file.getSourceUriOrPath(), file.getLocalFilePath(), file.getMimeType(), file.getCreationTime())); } imageBandView.setData(images); diff --git a/apptentive/src/main/res/layout/apptentive_message_auto.xml b/apptentive/src/main/res/layout/apptentive_message_auto.xml index 5fe4d0fca..11461b3b3 100644 --- a/apptentive/src/main/res/layout/apptentive_message_auto.xml +++ b/apptentive/src/main/res/layout/apptentive_message_auto.xml @@ -14,8 +14,7 @@ android:paddingTop="4dp" android:paddingBottom="8dp" android:paddingLeft="@dimen/apptentive_message_center_message_list_margin_side" - android:paddingRight="@dimen/apptentive_message_center_message_list_margin_side" - android:descendantFocusability="blocksDescendants"> + android:paddingRight="@dimen/apptentive_message_center_message_list_margin_side"> diff --git a/apptentive/src/main/res/layout/apptentive_message_incoming.xml b/apptentive/src/main/res/layout/apptentive_message_incoming.xml index 283817cb1..2431c88ca 100644 --- a/apptentive/src/main/res/layout/apptentive_message_incoming.xml +++ b/apptentive/src/main/res/layout/apptentive_message_incoming.xml @@ -9,8 +9,7 @@ + style="@style/Apptentive.MessageCenterMessageFrame"> + style="@style/Apptentive.MessageCenterMessageFrame"> @style/Apptentive.Style.Widget.FloatingActionButton @style/Apptentive.Style.Widget.SurveySentToast - true @android:color/transparent @null true false @android:style/Animation.Dialog + + true 2dp @@ -232,7 +233,6 @@ @null false false - false @null @null @android:style/Animation.Dialog From 3d84b6c0639bde21827068fa5c71f248cda8daf5 Mon Sep 17 00:00:00 2001 From: Barry Li Date: Thu, 5 May 2016 15:55:09 -0700 Subject: [PATCH 03/12] ANDROID-658 Fix issues in Android versions starting with API Level 19: setting translucent statusbar would have two implications: toolbar of non-model interaction would be partially covered; Keyboard launch won't resize window. --- .../android/sdk/ApptentiveViewActivity.java | 90 ++++++++++++++++++- .../fragment/MessageCenterFragment.java | 4 +- 2 files changed, 90 insertions(+), 4 deletions(-) diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/ApptentiveViewActivity.java b/apptentive/src/main/java/com/apptentive/android/sdk/ApptentiveViewActivity.java index eb01a62e9..a6ae1e507 100644 --- a/apptentive/src/main/java/com/apptentive/android/sdk/ApptentiveViewActivity.java +++ b/apptentive/src/main/java/com/apptentive/android/sdk/ApptentiveViewActivity.java @@ -11,8 +11,11 @@ import android.content.Intent; import android.content.pm.PackageManager; import android.content.res.Resources; +import android.content.res.TypedArray; import android.graphics.PorterDuff; +import android.graphics.Rect; import android.graphics.drawable.Drawable; +import android.os.Build; import android.os.Bundle; import android.support.v4.app.FragmentManager; @@ -24,6 +27,7 @@ import android.support.v7.widget.Toolbar; import android.view.MenuItem; import android.view.View; +import android.view.ViewTreeObserver; import android.view.WindowManager; import com.apptentive.android.sdk.adapter.ApptentiveViewPagerAdapter; @@ -47,12 +51,16 @@ public class ApptentiveViewActivity extends AppCompatActivity implements Apptent private int current_tab; + private View decorView; + private View contentView; + protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Bundle bundle = FragmentFactory.addDisplayModeToFragmentBundle(getIntent().getExtras()); + boolean isInteractionModel = bundle.getBoolean(Constants.FragmentConfigKeys.MODAL); // Add theme based on the display mode of the interaction: modal or not - applyApptentiveTheme(bundle.getBoolean(Constants.FragmentConfigKeys.MODAL)); + applyApptentiveTheme(isInteractionModel); ApptentiveBaseFragment newFragment = null; @@ -78,7 +86,8 @@ protected void onCreate(Bundle savedInstanceState) { bundle.putInt("toolbarLayoutId", R.id.apptentive_toolbar); if (newFragment == null) { newFragment = FragmentFactory.createFragmentInstance(bundle); - applyApptentiveTheme(newFragment.isShownAsModelDialog()); + isInteractionModel = newFragment.isShownAsModelDialog(); + applyApptentiveTheme(isInteractionModel); } if (newFragment != null) { newFragment.setOnTransitionListener(this); @@ -106,6 +115,12 @@ protected void onCreate(Bundle savedInstanceState) { toolbar = (Toolbar) findViewById(R.id.apptentive_toolbar); setSupportActionBar(toolbar); + + /* Add top padding by the amount of Status Bar height to avoid toolbar being covered when + * status bar is translucent + */ + toolbar.setPadding(0, getToolbarHeightAdjustment(!isInteractionModel), 0, 0); + ActionBar actionBar = getSupportActionBar(); if (actionBar != null) { @@ -288,4 +303,75 @@ private void startLauncherActivityIfRoot() { } } + /* Android versions starting with API Level 19, setting translucent statusbar would have two implications: + * 1. toolbar of non-model interaction would be partially covered + * 2. Keyboard launch won't resize window. (Bug: https://code.google.com/p/android/issues/detail?id=63777) + * The following method will fix both issues + */ + private int getToolbarHeightAdjustment(boolean bToolbarShown) { + int adjustAmount = 0; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { + boolean translucentStatus = false; + // check theme attrs to see if translucent statusbar is set explicitly + int[] attrs = {android.R.attr.windowTranslucentStatus}; + TypedArray a = ApptentiveInternal.getInstance().getApptentiveTheme().obtainStyledAttributes(attrs); + try { + translucentStatus = a.getBoolean(0, false); + } finally { + a.recycle(); + } + + // also check window flags in case translucent statusbar is set implicitly + WindowManager.LayoutParams winParams = getWindow().getAttributes(); + int bits = WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS; + if ((winParams.flags & bits) != 0) { + translucentStatus = true; + } + + if (translucentStatus) { + if (bToolbarShown) { + int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android"); + if (resourceId > 0) { + adjustAmount = getResources().getDimensionPixelSize(resourceId); + } + } + + /* Add layout listener to ensure keyboard launch resize the screen when android:windowTranslucentStatus=true + * Fixing workaround found here: + * http://stackoverflow.com/questions/8398102/androidwindowsoftinputmode-adjustresize-doesnt-make-any-difference + */ + decorView = getWindow().getDecorView(); + contentView = decorView.findViewById(android.R.id.content); + decorView.getViewTreeObserver().addOnGlobalLayoutListener(keyboardPresencelLayoutListener); + } + } + return adjustAmount; + } + + ViewTreeObserver.OnGlobalLayoutListener keyboardPresencelLayoutListener = new ViewTreeObserver.OnGlobalLayoutListener() { + @Override + public void onGlobalLayout() { + Rect r = new Rect(); + decorView.getWindowVisibleDisplayFrame(r); + + int height = decorView.getContext().getResources().getDisplayMetrics().heightPixels; + int diff = height - r.bottom; + + // Detect keyboard launch when use-able screen height differs from the total screen height + if (diff != 0) { + //check if the padding is 0 (if yes set the padding for the keyboard) + if (contentView.getPaddingBottom() != diff) { + //set the padding of the contentView for the keyboard + contentView.setPadding(0, 0, 0, diff); + } + } else { + //check if the padding is != 0 (if yes reset the padding) + if (contentView.getPaddingBottom() != 0) { + //reset the padding of the contentView + contentView.setPadding(0, 0, 0, 0); + } + } + } + }; + } diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/fragment/MessageCenterFragment.java b/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/fragment/MessageCenterFragment.java index 838ed28c0..f22700412 100644 --- a/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/fragment/MessageCenterFragment.java +++ b/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/fragment/MessageCenterFragment.java @@ -1264,8 +1264,8 @@ public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCoun @Override public void OnListViewResize(int w, int h, int oldw, int oldh) { - // detect keyboard launching - if (oldh > h) { + // detect keyboard launching. If height difference is more than 100 pixels, probably due to keyboard + if (oldh > h && oldh - h > 100) { if (composingItem != null) { // When keyboard is up, adjust the scolling such that the cursor is always visible final int firstIndex = messageCenterListView.getFirstVisiblePosition(); From 59bb8bea3c4af3f5bdbd9e7dbf0b7e08029f864b Mon Sep 17 00:00:00 2001 From: Barry Li Date: Thu, 5 May 2016 16:10:55 -0700 Subject: [PATCH 04/12] ANDROID-660 Fix horizontal padding in externded interaction header --- apptentive/src/main/res/layout/apptentive_survey.xml | 2 +- apptentive/src/main/res/values-sw360dp-port/dimens.xml | 1 + apptentive/src/main/res/values-sw600dp/dimens.xml | 1 + apptentive/src/main/res/values/dimens.xml | 1 + 4 files changed, 4 insertions(+), 1 deletion(-) diff --git a/apptentive/src/main/res/layout/apptentive_survey.xml b/apptentive/src/main/res/layout/apptentive_survey.xml index fa8a2fe5c..7efdedff4 100644 --- a/apptentive/src/main/res/layout/apptentive_survey.xml +++ b/apptentive/src/main/res/layout/apptentive_survey.xml @@ -25,7 +25,7 @@ android:paddingRight="@dimen/apptentive_interaction_extended_toolbar_margin_end" android:theme="?apptentiveToolbarTheme" android:background="?attr/colorPrimary"> - diff --git a/apptentive/src/main/res/values-sw360dp-port/dimens.xml b/apptentive/src/main/res/values-sw360dp-port/dimens.xml index 37674e49b..416b3208b 100644 --- a/apptentive/src/main/res/values-sw360dp-port/dimens.xml +++ b/apptentive/src/main/res/values-sw360dp-port/dimens.xml @@ -17,5 +17,6 @@ 60dp 8dp + @integer/match_parent \ No newline at end of file diff --git a/apptentive/src/main/res/values-sw600dp/dimens.xml b/apptentive/src/main/res/values-sw600dp/dimens.xml index 185528961..c5405ea26 100644 --- a/apptentive/src/main/res/values-sw600dp/dimens.xml +++ b/apptentive/src/main/res/values-sw600dp/dimens.xml @@ -16,6 +16,7 @@ 24sp 40dp + @integer/wrap_content 568dp \ No newline at end of file diff --git a/apptentive/src/main/res/values/dimens.xml b/apptentive/src/main/res/values/dimens.xml index d7090be84..18c9ec9e0 100644 --- a/apptentive/src/main/res/values/dimens.xml +++ b/apptentive/src/main/res/values/dimens.xml @@ -77,6 +77,7 @@ 60dp 60dp + @integer/wrap_content @integer/match_parent 56dp From 77a1ca9994d00413aabbf740c77c5daa1b4a6c65 Mon Sep 17 00:00:00 2001 From: Barry Li Date: Fri, 6 May 2016 14:22:09 -0700 Subject: [PATCH 05/12] ANDROID-658 PR feedbacks --- .../android/sdk/ApptentiveViewActivity.java | 28 +++++++++---------- .../fragment/ApptentiveBaseFragment.java | 2 +- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/ApptentiveViewActivity.java b/apptentive/src/main/java/com/apptentive/android/sdk/ApptentiveViewActivity.java index a6ae1e507..8c5ef8c16 100644 --- a/apptentive/src/main/java/com/apptentive/android/sdk/ApptentiveViewActivity.java +++ b/apptentive/src/main/java/com/apptentive/android/sdk/ApptentiveViewActivity.java @@ -58,9 +58,9 @@ protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Bundle bundle = FragmentFactory.addDisplayModeToFragmentBundle(getIntent().getExtras()); - boolean isInteractionModel = bundle.getBoolean(Constants.FragmentConfigKeys.MODAL); + boolean isInteractionModal = bundle.getBoolean(Constants.FragmentConfigKeys.MODAL); // Add theme based on the display mode of the interaction: modal or not - applyApptentiveTheme(isInteractionModel); + applyApptentiveTheme(isInteractionModal); ApptentiveBaseFragment newFragment = null; @@ -72,8 +72,8 @@ protected void onCreate(Bundle savedInstanceState) { * failure of retrieval indicate internal error */ if (newFragment == null) { - finish(); - return; + finish(); + return; } } try { @@ -86,8 +86,8 @@ protected void onCreate(Bundle savedInstanceState) { bundle.putInt("toolbarLayoutId", R.id.apptentive_toolbar); if (newFragment == null) { newFragment = FragmentFactory.createFragmentInstance(bundle); - isInteractionModel = newFragment.isShownAsModelDialog(); - applyApptentiveTheme(isInteractionModel); + isInteractionModal = newFragment.isShownAsModalDialog(); + applyApptentiveTheme(isInteractionModal); } if (newFragment != null) { newFragment.setOnTransitionListener(this); @@ -119,7 +119,7 @@ protected void onCreate(Bundle savedInstanceState) { /* Add top padding by the amount of Status Bar height to avoid toolbar being covered when * status bar is translucent */ - toolbar.setPadding(0, getToolbarHeightAdjustment(!isInteractionModel), 0, 0); + toolbar.setPadding(0, getToolbarHeightAdjustment(!isInteractionModal), 0, 0); ActionBar actionBar = getSupportActionBar(); @@ -157,7 +157,7 @@ protected void onCreate(Bundle savedInstanceState) { @Override public void onPageSelected(int position) { ApptentiveBaseFragment currentFragment = (ApptentiveBaseFragment) viewPager_Adapter.getItem(viewPager.getCurrentItem()); - if (!currentFragment.isShownAsModelDialog()) { + if (!currentFragment.isShownAsModalDialog()) { final String title = currentFragment.getTitle(); toolbar.post(new Runnable() { @@ -252,7 +252,7 @@ public void onSaveInstanceState(Bundle outState) { public void onFragmentTransition(ApptentiveBaseFragment currentFragment) { if (currentFragment != null) { int numberOfPages = viewPager_Adapter.getCount(); - for (int i = 0; i< numberOfPages; ++i) { + for (int i = 0; i < numberOfPages; ++i) { ApptentiveBaseFragment fragment = (ApptentiveBaseFragment) viewPager_Adapter.getItem(i); if (currentFragment == fragment) { if (numberOfPages == 1) { @@ -304,10 +304,10 @@ private void startLauncherActivityIfRoot() { } /* Android versions starting with API Level 19, setting translucent statusbar would have two implications: - * 1. toolbar of non-model interaction would be partially covered - * 2. Keyboard launch won't resize window. (Bug: https://code.google.com/p/android/issues/detail?id=63777) - * The following method will fix both issues - */ + * 1. toolbar of non-model interaction would be partially covered + * 2. Keyboard launch won't resize window. (Bug: https://code.google.com/p/android/issues/detail?id=63777) + * The following method will fix both issues + */ private int getToolbarHeightAdjustment(boolean bToolbarShown) { int adjustAmount = 0; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { @@ -373,5 +373,5 @@ public void onGlobalLayout() { } } }; - + } diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/fragment/ApptentiveBaseFragment.java b/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/fragment/ApptentiveBaseFragment.java index 785fa14c0..45c88250d 100644 --- a/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/fragment/ApptentiveBaseFragment.java +++ b/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/interaction/fragment/ApptentiveBaseFragment.java @@ -383,7 +383,7 @@ public Activity getActivity(Fragment fragment) { } } - public boolean isShownAsModelDialog() { + public boolean isShownAsModalDialog() { Bundle bundle = getArguments(); if (bundle != null) { From 9ec6455b69fe502b2f2529dfe21625672a6c5884 Mon Sep 17 00:00:00 2001 From: Barry Li Date: Mon, 9 May 2016 10:50:18 -0700 Subject: [PATCH 06/12] Bump build number to 3.0.1 --- .../main/java/com/apptentive/android/sdk/util/Constants.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/util/Constants.java b/apptentive/src/main/java/com/apptentive/android/sdk/util/Constants.java index 48604160f..b357898a8 100644 --- a/apptentive/src/main/java/com/apptentive/android/sdk/util/Constants.java +++ b/apptentive/src/main/java/com/apptentive/android/sdk/util/Constants.java @@ -11,7 +11,7 @@ */ public class Constants { - public static final String APPTENTIVE_SDK_VERSION = "3.0.0"; + public static final String APPTENTIVE_SDK_VERSION = "3.0.1"; public static final int REQUEST_CODE_PHOTO_FROM_SYSTEM_PICKER = 10; From c3ba569da8be201d36f37a95769837eaa20893c9 Mon Sep 17 00:00:00 2001 From: Barry Li Date: Sat, 21 May 2016 13:27:47 -0700 Subject: [PATCH 07/12] Fix the issue where the thumbnail of the current foreground Apptentive activity in task list was not picking up the custom color applied to Apptentive on Lollipop and later --- .../apptentive/android/sdk/ApptentiveViewActivity.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/ApptentiveViewActivity.java b/apptentive/src/main/java/com/apptentive/android/sdk/ApptentiveViewActivity.java index 8c5ef8c16..99ecd6291 100644 --- a/apptentive/src/main/java/com/apptentive/android/sdk/ApptentiveViewActivity.java +++ b/apptentive/src/main/java/com/apptentive/android/sdk/ApptentiveViewActivity.java @@ -7,6 +7,7 @@ package com.apptentive.android.sdk; +import android.app.ActivityManager; import android.content.ComponentName; import android.content.Intent; import android.content.pm.PackageManager; @@ -274,6 +275,13 @@ private void applyApptentiveTheme(boolean isModalInteraction) { apptentiveTheme.applyStyle(R.style.ApptentiveBaseDialogTheme, true); } getTheme().setTo(apptentiveTheme); + + // Change the thumbnail header color in task list + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + int colorPrimary = Util.getThemeColor(apptentiveTheme, R.attr.colorPrimary); + ActivityManager.TaskDescription taskDes = new ActivityManager.TaskDescription(null, null, colorPrimary); + setTaskDescription(taskDes); + } } private void addFragmentToAdapter(ApptentiveBaseFragment f, String title) { From 3d07413e313e9cfd64f641ade87bc7140e782a96 Mon Sep 17 00:00:00 2001 From: Barry Li Date: Mon, 23 May 2016 02:02:24 -0700 Subject: [PATCH 08/12] Application foreground and background tracking using onActivityStarted and onActivityStopped(). --- .../android/sdk/ApptentiveInternal.java | 16 ++----- .../ApptentiveActivityLifecycleCallbacks.java | 47 +++++++++---------- 2 files changed, 24 insertions(+), 39 deletions(-) diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/ApptentiveInternal.java b/apptentive/src/main/java/com/apptentive/android/sdk/ApptentiveInternal.java index 996da2b5a..62d04e6d3 100644 --- a/apptentive/src/main/java/com/apptentive/android/sdk/ApptentiveInternal.java +++ b/apptentive/src/main/java/com/apptentive/android/sdk/ApptentiveInternal.java @@ -384,11 +384,8 @@ public void onAppExit(final Context appContext) { public void onActivityStarted(Activity activity) { if (activity != null) { currentTaskStackTopActivity = new WeakReference(activity); + messageManager.setCurrentForgroundActivity(currentTaskStackTopActivity); } - } - - public void onActivityResumed(Activity activity) { - messageManager.setCurrentForgroundActivity(activity); checkAndUpdateApptentiveConfigurations(); @@ -397,15 +394,6 @@ public void onActivityResumed(Activity activity) { syncPerson(); } - public void onActivityDestroyed(Activity activity) { - if (activity != null && currentTaskStackTopActivity != null) { - Activity currentBottomActivity = currentTaskStackTopActivity.get(); - if (currentBottomActivity != null && currentBottomActivity == activity) { - currentTaskStackTopActivity = null; - } - } - } - public void onAppEnterForeground() { appIsInForeground = true; payloadWorker.appWentToForeground(); @@ -414,6 +402,8 @@ public void onAppEnterForeground() { public void onAppEnterBackground() { appIsInForeground = false; + currentTaskStackTopActivity = null; + messageManager.setCurrentForgroundActivity(null); payloadWorker.appWentToBackground(); messageManager.appWentToBackground(); } diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/lifecycle/ApptentiveActivityLifecycleCallbacks.java b/apptentive/src/main/java/com/apptentive/android/sdk/lifecycle/ApptentiveActivityLifecycleCallbacks.java index 5c4a5e553..6cd0b759d 100644 --- a/apptentive/src/main/java/com/apptentive/android/sdk/lifecycle/ApptentiveActivityLifecycleCallbacks.java +++ b/apptentive/src/main/java/com/apptentive/android/sdk/lifecycle/ApptentiveActivityLifecycleCallbacks.java @@ -32,11 +32,6 @@ public ApptentiveActivityLifecycleCallbacks() { @Override public void onActivityStarted(Activity activity) { - ApptentiveInternal.getInstance().onActivityStarted(activity); - } - - @Override - public void onActivityResumed(Activity activity) { boolean wasAppBackground = !isAppForeground; isAppForeground = true; @@ -49,12 +44,29 @@ public void onActivityResumed(Activity activity) { appEnteredForeground(); } - ApptentiveInternal.getInstance().onActivityResumed(activity); + ApptentiveInternal.getInstance().onActivityStarted(activity); + } + + @Override + public void onActivityResumed(Activity activity) { } @Override public void onActivityPaused(final Activity activity) { + } + + @Override + public void onActivityDestroyed(final Activity activity) { + } + + @Override + public void onActivityCreated(Activity activity, Bundle savedInstanceState) { + + } + + @Override + public void onActivityStopped(Activity activity) { if (foregroundActivities.decrementAndGet() < 0) { ApptentiveLog.e("Incorrect number of foreground Activities encountered. Resetting to 0."); foregroundActivities.set(0); @@ -63,8 +75,9 @@ public void onActivityPaused(final Activity activity) { if (checkFgBgRoutine != null) { delayedChecker.removeCallbacks(checkFgBgRoutine); } - /* When one activity transits to another one, there is a brief period during which the former - * is paused but the latter has not yet resumed. To prevent false negative, check routine is + + /* When one activity transits to another one, there is a brief period during which the former + * is paused but the latter has not yet resumed. To prevent false negative, check routine is * delayed */ delayedChecker.postDelayed(checkFgBgRoutine = new Runnable() { @@ -77,24 +90,6 @@ public void run() { } }, CHECK_DELAY_SHORT); - - ApptentiveInternal.getInstance().getMessageManager().setCurrentForgroundActivity(null); - - } - - @Override - public void onActivityDestroyed(final Activity activity) { - ApptentiveInternal.getInstance().onActivityDestroyed(activity); - } - - @Override - public void onActivityCreated(Activity activity, Bundle savedInstanceState) { - - } - - @Override - public void onActivityStopped(Activity activity) { - } @Override From c2ce9cb9be029034b9098fe4e7101b569926b85f Mon Sep 17 00:00:00 2001 From: Barry Li Date: Mon, 23 May 2016 19:36:19 -0700 Subject: [PATCH 09/12] ANDROID-671 app fg/bg tracking: add more comments and clean up codes --- .../apptentive/android/sdk/ApptentiveInternal.java | 12 +++++++----- .../sdk/module/messagecenter/MessageManager.java | 6 +++--- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/ApptentiveInternal.java b/apptentive/src/main/java/com/apptentive/android/sdk/ApptentiveInternal.java index 62d04e6d3..3a88bc045 100644 --- a/apptentive/src/main/java/com/apptentive/android/sdk/ApptentiveInternal.java +++ b/apptentive/src/main/java/com/apptentive/android/sdk/ApptentiveInternal.java @@ -107,6 +107,7 @@ public class ApptentiveInternal { ExecutorService cachedExecutor; + // Holds reference to the current foreground activity of the host app private WeakReference currentTaskStackTopActivity; // Used for temporarily holding customData that needs to be sent on the next message the consumer sends. @@ -252,11 +253,11 @@ public Context getApplicationContext() { return appContext; } - /* Get the last running activity from the current application, i.e. at the top of the task - * It is tracked through {@link #onActivityStarted(Activity)} and {@link #onActivityDestroyed(Activity)} + /* Get the foreground activity from the current application, i.e. at the top of the task + * It is tracked through {@link #onActivityStarted(Activity)} and {@link #onActivityStopped(Activity)} * - * If Apptentive interaction is to be launched from a non-activity context, use the last running activity at - * the top of the task. + * If Apptentive interaction is to be launched from a non-activity context, use the current activity at + * the top of the task stack, i.e. the foreground activity. */ public Activity getCurrentTaskStackTopActivity() { if (currentTaskStackTopActivity != null) { @@ -383,8 +384,9 @@ public void onAppExit(final Context appContext) { public void onActivityStarted(Activity activity) { if (activity != null) { + // Set current foreground activity reference whenever a new activity is started currentTaskStackTopActivity = new WeakReference(activity); - messageManager.setCurrentForgroundActivity(currentTaskStackTopActivity); + messageManager.setCurrentForgroundActivity(activity); } checkAndUpdateApptentiveConfigurations(); diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/module/messagecenter/MessageManager.java b/apptentive/src/main/java/com/apptentive/android/sdk/module/messagecenter/MessageManager.java index 75def8ead..9f3c559ea 100644 --- a/apptentive/src/main/java/com/apptentive/android/sdk/module/messagecenter/MessageManager.java +++ b/apptentive/src/main/java/com/apptentive/android/sdk/module/messagecenter/MessageManager.java @@ -422,12 +422,12 @@ public void notifyHostUnreadMessagesListeners(int unreadMessages) { } } - // Set when Activity.onResume() is called + // Set when Activity.onStart() and onStop() are called public void setCurrentForgroundActivity(Activity activity) { if (activity != null) { currentForgroundApptentiveActivity = new WeakReference(activity); - } else if (currentForgroundApptentiveActivity != null) { - ApptentiveToastNotificationManager manager = ApptentiveToastNotificationManager.getInstance(currentForgroundApptentiveActivity.get(), false); + } else { + ApptentiveToastNotificationManager manager = ApptentiveToastNotificationManager.getInstance(null, false); if (manager != null) { manager.cleanUp(); } From 1c04fba10d444a349c5894973ac0fc0f7d599128 Mon Sep 17 00:00:00 2001 From: Barry Li Date: Tue, 24 May 2016 16:58:08 -0700 Subject: [PATCH 10/12] ANDROID-677 tracking top activity using onResume() --- .../com/apptentive/android/sdk/ApptentiveInternal.java | 9 +++++++++ .../lifecycle/ApptentiveActivityLifecycleCallbacks.java | 1 + 2 files changed, 10 insertions(+) diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/ApptentiveInternal.java b/apptentive/src/main/java/com/apptentive/android/sdk/ApptentiveInternal.java index 3a88bc045..cdb10cc8d 100644 --- a/apptentive/src/main/java/com/apptentive/android/sdk/ApptentiveInternal.java +++ b/apptentive/src/main/java/com/apptentive/android/sdk/ApptentiveInternal.java @@ -396,6 +396,15 @@ public void onActivityStarted(Activity activity) { syncPerson(); } + public void onActivityResumed(Activity activity) { + if (activity != null) { + // Set current foreground activity reference whenever a new activity is started + currentTaskStackTopActivity = new WeakReference(activity); + messageManager.setCurrentForgroundActivity(activity); + } + + } + public void onAppEnterForeground() { appIsInForeground = true; payloadWorker.appWentToForeground(); diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/lifecycle/ApptentiveActivityLifecycleCallbacks.java b/apptentive/src/main/java/com/apptentive/android/sdk/lifecycle/ApptentiveActivityLifecycleCallbacks.java index 6cd0b759d..f458e0b34 100644 --- a/apptentive/src/main/java/com/apptentive/android/sdk/lifecycle/ApptentiveActivityLifecycleCallbacks.java +++ b/apptentive/src/main/java/com/apptentive/android/sdk/lifecycle/ApptentiveActivityLifecycleCallbacks.java @@ -49,6 +49,7 @@ public void onActivityStarted(Activity activity) { @Override public void onActivityResumed(Activity activity) { + ApptentiveInternal.getInstance().onActivityResumed(activity); } @Override From 75d8694bf3b90f9efc12fa82ce743d267087ba15 Mon Sep 17 00:00:00 2001 From: Barry Li Date: Tue, 24 May 2016 16:59:36 -0700 Subject: [PATCH 11/12] ANDROID-675 Borderless button text color state list can't use attribute on pre-23 --- .../sdk/module/engagement/EngagementModule.java | 3 ++- ...ntive_interaction_button_color_state_list.xml | 6 +++--- .../main/res/layout/apptentive_dialog_alert.xml | 4 ++-- .../apptentive_message_center_who_card.xml | 4 ++-- apptentive/src/main/res/values-v21/styles.xml | 10 ---------- apptentive/src/main/res/values-v23/styles.xml | 16 ++++++++++++++++ apptentive/src/main/res/values/styles.xml | 2 ++ 7 files changed, 27 insertions(+), 18 deletions(-) create mode 100644 apptentive/src/main/res/values-v23/styles.xml diff --git a/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/EngagementModule.java b/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/EngagementModule.java index f9a55494f..2d518cf05 100644 --- a/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/EngagementModule.java +++ b/apptentive/src/main/java/com/apptentive/android/sdk/module/engagement/EngagementModule.java @@ -85,11 +85,12 @@ public static void launchInteraction(Context context, Interaction interaction) { * ContentProvider, and BroadcastReceiver */ if (!(context instanceof Activity)) { - // check if any activity from the hosting app is running + // check if any activity from the hosting app is running at foreground Activity activity = ApptentiveInternal.getInstance().getCurrentTaskStackTopActivity(); if (activity != null) { context = activity; } else { + // If no foreground activity from the host app, launch Apptentive interaction as a new task intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK); } } diff --git a/apptentive/src/main/res/color/apptentive_interaction_button_color_state_list.xml b/apptentive/src/main/res/color/apptentive_interaction_button_color_state_list.xml index 6d82798a1..3069be385 100644 --- a/apptentive/src/main/res/color/apptentive_interaction_button_color_state_list.xml +++ b/apptentive/src/main/res/color/apptentive_interaction_button_color_state_list.xml @@ -13,12 +13,12 @@ will always have apptentiveInteractionButtonColorDefault. However, host app may provide an override color state list style with static values to achieve the desired effects on - both pre-21 and post-21: + both pre-23 and post-23: In ApptentiveThemeOverride.xml: - @style/CutomButtonStyle + @style/CustomButtonStyle Define style as: - Define color as: diff --git a/apptentive/src/main/res/layout/apptentive_dialog_alert.xml b/apptentive/src/main/res/layout/apptentive_dialog_alert.xml index e987a9782..aee1f5e0d 100644 --- a/apptentive/src/main/res/layout/apptentive_dialog_alert.xml +++ b/apptentive/src/main/res/layout/apptentive_dialog_alert.xml @@ -49,7 +49,7 @@