Skip to content

Commit

Permalink
Merge pull request #358 from apptentive/patch
Browse files Browse the repository at this point in the history
3.1.1 Patch
  • Loading branch information
skykelsey authored Jun 21, 2016
2 parents b6ac626 + d5626d4 commit 07ea2de
Show file tree
Hide file tree
Showing 8 changed files with 150 additions and 99 deletions.
12 changes: 0 additions & 12 deletions .idea/runConfigurations.xml

This file was deleted.

11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
# 2016-06-20 - 3.1.1

#### Improvements

* Defer message polling task until Message Center is opened, UnreadMessagesListener is registered, or a Push is received.
* Add internal method to set the application theme programmatically from which the Apptentive UI will inherit styles.

#### Bugs Fixed

* statusBarColor attribute was causing run-time exception on pre-21 devices.

# 2016-06-08 - 3.1.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.1.0|aar)
##### Binary releases are hosted for Maven [here](http://search.maven.org/#artifactdetails|com.apptentive|apptentive-android|3.1.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
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,8 @@ public class ApptentiveInternal {
// toolbar theme specified in R.attr.apptentiveToolbarTheme
Resources.Theme apptentiveToolbarTheme;

// app default theme res id, if specified in app AndroidManifest
int appDefaultThemeId;
// app default appcompat theme res id, if specified in app AndroidManifest
int appDefaultAppCompatThemeId;

int statusBarColorDefault;
String defaultAppDisplayName = "this app";
Expand Down Expand Up @@ -137,9 +137,6 @@ public static PushAction parse(String name) {

private static volatile ApptentiveInternal sApptentiveInternal;

ApptentiveInternal() {
}


public static boolean isApptentiveRegistered() {
return (sApptentiveInternal != null);
Expand Down Expand Up @@ -208,7 +205,9 @@ public static ApptentiveInternal getInstance() {
synchronized (ApptentiveInternal.class) {
if (sApptentiveInternal != null && !isApptentiveInitialized.get()) {
isApptentiveInitialized.set(true);
sApptentiveInternal.init();
if (!sApptentiveInternal.init()) {
ApptentiveLog.e("Apptentive init() failed");
}
}
}
}
Expand Down Expand Up @@ -249,11 +248,45 @@ static void setLifeCycleCallback() {
synchronized (ApptentiveInternal.class) {
if (sApptentiveInternal != null && sApptentiveInternal.lifecycleCallbacks == null &&
sApptentiveInternal.appContext instanceof Application) {
sApptentiveInternal.lifecycleCallbacks = new ApptentiveActivityLifecycleCallbacks();
((Application) sApptentiveInternal.appContext).registerActivityLifecycleCallbacks(sApptentiveInternal.lifecycleCallbacks);
sApptentiveInternal.lifecycleCallbacks = new ApptentiveActivityLifecycleCallbacks();
((Application) sApptentiveInternal.appContext).registerActivityLifecycleCallbacks(sApptentiveInternal.lifecycleCallbacks);
}
}
}
}


/*
* Set default theme whom Apptentive UI will inherit theme attributes from. Apptentive will only
* inherit from an AppCompat theme
* @param themeResId : resource id of the theme style definition, such as R.style.MyAppTheme
* @return true if the theme is set for inheritance successfully.
*/
public boolean setApplicationDefaultTheme(int themeResId) {
try {
if (themeResId != 0) {
// If passed theme res id does not exist, an exception would be thrown and caught
appContext.getResources().getResourceName(themeResId);

// Check if the theme to be inheritd from is an AppCompat theme.
Resources.Theme appDefaultTheme = appContext.getResources().newTheme();
appDefaultTheme.applyStyle(themeResId, true);

TypedArray a = appDefaultTheme.obtainStyledAttributes(android.support.v7.appcompat.R.styleable.AppCompatTheme);
try {
if (a.hasValue(android.support.v7.appcompat.R.styleable.AppCompatTheme_colorPrimaryDark)) {
// Only set to use if it's an AppCompat theme. See updateApptentiveInteractionTheme() for theme inheritance chain
appDefaultAppCompatThemeId = themeResId;
return true;
}
} finally {
a.recycle();
}
}
} catch (Resources.NotFoundException e) {
ApptentiveLog.e("Theme Res id not found");
}
return false;
}

/*
Expand Down Expand Up @@ -445,29 +478,17 @@ public void onAppEnterBackground() {
*/
public void updateApptentiveInteractionTheme(Resources.Theme interactionTheme, Context context) {
/* Step 1: Apply Apptentive default theme layer.
* If host activity is an Apptentive activity, the base theme already has Apptentive defaults applied, so skip Step 1.
* If parent activity is NOT an Apptentive activity, first apply Apptentive defaults.
* If host activity is an activity, the base theme already has Apptentive defaults applied, so skip Step 1.
* If parent activity is NOT an activity, first apply Apptentive defaults.
*/
if (!(context instanceof Activity)) {
// If host context is not an activity, i.e. application context, treat it as initial theme setup
interactionTheme.applyStyle(R.style.ApptentiveTheme_Base_Versioned, true);
}

// Step 2: Inherit app default theme if there is one specified in app's AndroidManifest
if (appDefaultThemeId != 0) {
Resources.Theme appDefaultTheme = context.getResources().newTheme();
appDefaultTheme.applyStyle(appDefaultThemeId, true);

// If the app contains colorPrimaryDark, it is using an AppCompat theme. Therefore, we want to use it.
// If it's not using an AppCompat theme, we don't want to apply it to our SDK, and use our default theme instead.
TypedArray a = appDefaultTheme.obtainStyledAttributes(android.support.v7.appcompat.R.styleable.AppCompatTheme);
try {
if (a.hasValue(android.support.v7.appcompat.R.styleable.AppCompatTheme_colorPrimaryDark)) {
interactionTheme.applyStyle(appDefaultThemeId, true);
}
} finally {
a.recycle();
}
// Step 2: Inherit app default appcompat theme if there is one specified in app's AndroidManifest
if (appDefaultAppCompatThemeId != 0) {
interactionTheme.applyStyle(appDefaultAppCompatThemeId, true);
}

// Step 3: Restore Apptentive UI window properties that may have been overridden in Step 2. This theme
Expand All @@ -481,26 +502,43 @@ public void updateApptentiveInteractionTheme(Resources.Theme interactionTheme, C
interactionTheme.applyStyle(themeOverrideResId, true);
}

int transparentColor = ContextCompat.getColor(context, android.R.color.transparent);
TypedArray a = interactionTheme.obtainStyledAttributes(new int[]{android.R.attr.statusBarColor});
try {
statusBarColorDefault = a.getColor(0, transparentColor);
} finally {
a.recycle();
// Step 5: Update statusbar color
/* Obtain the default statusbar color. When Apptentive Modal interaction is shown,
* a translucent overlay would be applied on top of statusBarColorDefault
*/
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
int transparentColor = ContextCompat.getColor(context, android.R.color.transparent);
TypedArray a = interactionTheme.obtainStyledAttributes(new int[]{android.R.attr.statusBarColor});
try {
statusBarColorDefault = a.getColor(0, transparentColor);
} finally {
a.recycle();
}
}

// Step 6: Update toolbar overlay theme
int toolbarThemeId = Util.getResourceIdFromAttribute(interactionTheme, R.attr.apptentiveToolbarTheme);
apptentiveToolbarTheme.setTo(interactionTheme);
apptentiveToolbarTheme.applyStyle(toolbarThemeId, true);
}

public void init() {

public boolean init() {
boolean bRet = true;
codePointStore.init();
messageManager.init();
/* If Message Center feature has never been used before, don't initialize message polling thread.
* Message Center feature will be seen as used, if one of the following conditions has been met:
* 1. Message Center has been opened for the first time
* 2. The first Push is received which would open Message Center
* 3. An unreadMessageCountListener() is set up
*/
boolean featureEverUsed = prefs.getBoolean(Constants.PREF_KEY_MESSAGE_CENTER_FEATURE_USED, false);
if (featureEverUsed) {
messageManager.init();
}
conversationToken = prefs.getString(Constants.PREF_KEY_CONVERSATION_TOKEN, null);
conversationId = prefs.getString(Constants.PREF_KEY_CONVERSATION_ID, null);
personId = prefs.getString(Constants.PREF_KEY_PERSON_ID, null);
apptentiveToolbarTheme = appContext.getResources().newTheme();

boolean apptentiveDebug = false;
String logLevelOverride = null;
Expand All @@ -519,31 +557,10 @@ public void init() {
isAppDebuggable = (ai.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
}

/*
* Construct the theme used by Apptentive Ui in the following order
* 1. start with Apptentive default theme : ApptentiveTheme.Base.Versioned
* 2. merge with app default theme, if one is specified and it's a AppCompat theme.
* (merge takes value from app default theme if both define the same attribute)
* 3. apply Apptentive UI specific frame style
* 4. Apply apptentive theme override specified by the app in ApptentiveThemeOverride
*/
appDefaultThemeId = ai.theme;
boolean appHasTheme = appDefaultThemeId != 0;
boolean appThemeIsAppCompatTheme = false;

apptentiveToolbarTheme = appContext.getResources().newTheme();

// Step 2, check if app specifies a default appcompat theme
if (appHasTheme) {
Resources.Theme appDefaultTheme = appContext.getResources().newTheme();
appDefaultTheme.applyStyle(appDefaultThemeId, true);

// If the app contains colorPrimaryDark, it is using an AppCompat theme. Therefore, we want to use it.
// If it's not using an AppCompat theme, we don't want to apply it to our SDK, and use our default theme instead.
appThemeIsAppCompatTheme = Util.getThemeColor(appDefaultTheme, R.attr.colorPrimaryDark) != 0;

}
// If the app default theme specified in AndroidManifest is an AppCompat theme, use it for Apptentive theme inheritance.
boolean appThemeIsAppCompatTheme = setApplicationDefaultTheme(ai.theme);

// check if host app defines an apptentive theme override
int themeOverrideResId = appContext.getResources().getIdentifier("ApptentiveThemeOverride", "style", appPackageName);

Integer currentVersionCode = packageInfo.versionCode;
Expand All @@ -555,6 +572,7 @@ public void init() {
appRelease.setBuildNumber(String.valueOf(currentVersionCode));
appRelease.setTargetSdkVersion(String.valueOf(packageInfo.applicationInfo.targetSdkVersion));
appRelease.setAppStore(Util.getInstallerPackageName(appContext));
// Set Apptentive theme inheritance metrics
appRelease.setInheritStyle(appThemeIsAppCompatTheme);
appRelease.setOverrideStyle(themeOverrideResId != 0);

Expand All @@ -580,8 +598,10 @@ public void init() {

} catch (Exception e) {
ApptentiveLog.e("Unexpected error while reading application or package info.", e);
bRet = false;
}


// Set debuggable and appropriate log level.
if (apptentiveDebug) {
ApptentiveLog.i("Apptentive debug logging set to VERBOSE.");
Expand Down Expand Up @@ -624,6 +644,7 @@ public void init() {
ApptentiveLog.d("Android ID: ", androidId);
ApptentiveLog.d("Default Locale: %s", Locale.getDefault().toString());
ApptentiveLog.d("Conversation id: %s", prefs.getString(Constants.PREF_KEY_CONVERSATION_ID, "null"));
return bRet;
}

private void onVersionChanged(Integer previousVersionCode, Integer currentVersionCode, String previousVersionName, String currentVersionName, AppRelease currentAppRelease) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -269,18 +269,22 @@ public void onFragmentTransition(ApptentiveBaseFragment currentFragment) {

private void applyApptentiveTheme(boolean isModalInteraction) {
// Update the activity theme to reflect current attributes
ApptentiveInternal.getInstance().updateApptentiveInteractionTheme(getTheme(), this);
try {
ApptentiveInternal.getInstance().updateApptentiveInteractionTheme(getTheme(), this);

if (isModalInteraction) {
getTheme().applyStyle(R.style.ApptentiveBaseDialogTheme, true);
setStatusBarColor(ApptentiveInternal.getInstance().getDefaultStatusbarColor());
}
if (isModalInteraction) {
getTheme().applyStyle(R.style.ApptentiveBaseDialogTheme, true);
setStatusBarColor();
}

// Change the thumbnail header color in task list
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
int colorPrimary = Util.getThemeColor(getTheme(), R.attr.colorPrimary);
ActivityManager.TaskDescription taskDes = new ActivityManager.TaskDescription(null, null, colorPrimary);
setTaskDescription(taskDes);
// Change the thumbnail header color in task list
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
int colorPrimary = Util.getThemeColor(getTheme(), R.attr.colorPrimary);
ActivityManager.TaskDescription taskDes = new ActivityManager.TaskDescription(null, null, colorPrimary);
setTaskDescription(taskDes);
}
} catch (Exception e) {
ApptentiveLog.e("Error apply Apptentive Theme.", e);
}
}

Expand Down Expand Up @@ -387,9 +391,10 @@ public void onGlobalLayout() {
* color defined by apptentive_activity_frame
* @param statusBarDefaultColor the default activity status bar color specified by the app
*/
private void setStatusBarColor(int statusBarDefaultColor) {
private void setStatusBarColor() {
// Changing status bar color is a post-21 feature
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
int statusBarDefaultColor = ApptentiveInternal.getInstance().getDefaultStatusbarColor();
int overlayColor = ContextCompat.getColor(this, R.color.apptentive_activity_frame_dark);
getWindow().setStatusBarColor(Util.alphaMixColors(statusBarDefaultColor, overlayColor));
}
Expand Down
Loading

0 comments on commit 07ea2de

Please sign in to comment.