Skip to content

Commit

Permalink
Merge branch 'patch'
Browse files Browse the repository at this point in the history
  • Loading branch information
skykelsey committed May 26, 2016
2 parents c6dd7c6 + 3c51f5b commit e21f28b
Show file tree
Hide file tree
Showing 31 changed files with 218 additions and 113 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
# 2016-05-25 - 3.0.1

#### Bugs Fixed

* Thumbnail in Recents Screen was not using host app's theme when the top Activity was an Apptentive Activity.
* Improve foreground / background detection.
* Fix borderless button styling before API level 23.
* Fix our UI to work better when the host app uses a translucent status bar.
* Fix window panning issue that can result in the keyboard coering part of a survey.

# 2016-04-26 - 3.0.0

#### Improvements
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use your app, to talk to them at the right time, and in the right way.

##### Version history is tracked [here](CHANGELOG.md)

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

We encourage you to help us find and fix bugs. If you find a bug, please fill in the contributor agreement, then open a [github issue](https://github.com/apptentive/apptentive-android/issues?direction=desc&sort=created&state=open).
Expand Down
16 changes: 8 additions & 8 deletions apptentive/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ public class ApptentiveInternal {

ExecutorService cachedExecutor;

// Holds reference to the current foreground activity of the host app
private WeakReference<Activity> currentTaskStackTopActivity;

// Used for temporarily holding customData that needs to be sent on the next message the consumer sends.
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -383,12 +384,10 @@ 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>(activity);
messageManager.setCurrentForgroundActivity(activity);
}
}

public void onActivityResumed(Activity activity) {
messageManager.setCurrentForgroundActivity(activity);

checkAndUpdateApptentiveConfigurations();

Expand All @@ -397,13 +396,13 @@ 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 onActivityResumed(Activity activity) {
if (activity != null) {
// Set current foreground activity reference whenever a new activity is started
currentTaskStackTopActivity = new WeakReference<Activity>(activity);
messageManager.setCurrentForgroundActivity(activity);
}

}

public void onAppEnterForeground() {
Expand All @@ -414,6 +413,8 @@ public void onAppEnterForeground() {

public void onAppEnterBackground() {
appIsInForeground = false;
currentTaskStackTopActivity = null;
messageManager.setCurrentForgroundActivity(null);
payloadWorker.appWentToBackground();
messageManager.appWentToBackground();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,16 @@
package com.apptentive.android.sdk;


import android.app.ActivityManager;
import android.content.ComponentName;
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;

Expand All @@ -24,6 +28,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;
Expand All @@ -47,12 +52,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 isInteractionModal = 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(isInteractionModal);


ApptentiveBaseFragment newFragment = null;
Expand All @@ -64,8 +73,8 @@ protected void onCreate(Bundle savedInstanceState) {
* failure of retrieval indicate internal error
*/
if (newFragment == null) {
finish();
return;
finish();
return;
}
}
try {
Expand All @@ -78,7 +87,8 @@ protected void onCreate(Bundle savedInstanceState) {
bundle.putInt("toolbarLayoutId", R.id.apptentive_toolbar);
if (newFragment == null) {
newFragment = FragmentFactory.createFragmentInstance(bundle);
applyApptentiveTheme(newFragment.isShownAsModelDialog());
isInteractionModal = newFragment.isShownAsModalDialog();
applyApptentiveTheme(isInteractionModal);
}
if (newFragment != null) {
newFragment.setOnTransitionListener(this);
Expand Down Expand Up @@ -106,6 +116,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(!isInteractionModal), 0, 0);

ActionBar actionBar = getSupportActionBar();

if (actionBar != null) {
Expand Down Expand Up @@ -142,7 +158,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() {
Expand Down Expand Up @@ -237,7 +253,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) {
Expand All @@ -259,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) {
Expand Down Expand Up @@ -288,4 +311,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);
}
}
}
};

}
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -49,12 +44,30 @@ public void onActivityResumed(Activity activity) {
appEnteredForeground();
}

ApptentiveInternal.getInstance().onActivityStarted(activity);
}

@Override
public void onActivityResumed(Activity activity) {
ApptentiveInternal.getInstance().onActivityResumed(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);
Expand All @@ -63,8 +76,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() {
Expand All @@ -77,24 +91,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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
Expand Down
Loading

0 comments on commit e21f28b

Please sign in to comment.