/** * For in-app messages that have a preferred orientation, locks the screen orientation and returns * true if the screen is currently in the preferred orientation. If the screen is not currently in * the preferred orientation, returns false. * * <p>Always returns true for tablets, regardless of current orientation. * * <p>Always returns true if the in-app message doesn't have a preferred orientation. * * @param inAppMessage * @return */ boolean verifyOrientationStatus(IInAppMessage inAppMessage) { if (ViewUtils.isRunningOnTablet(mActivity)) { AppboyLogger.d(TAG, "Running on tablet. In-app message can be displayed in any orientation."); return true; } Orientation preferredOrientation = inAppMessage.getOrientation(); if (preferredOrientation == null) { AppboyLogger.d( TAG, "No orientation specified. In-app message can be displayed in any orientation."); return true; } if (preferredOrientation == Orientation.ANY) { AppboyLogger.d( TAG, "Any orientation specified. In-app message can be displayed in any orientation."); return true; } int currentScreenOrientation = mActivity.getResources().getConfiguration().orientation; if (currentOrientationIsValid(currentScreenOrientation, preferredOrientation)) { if (mOriginalOrientation == null) { AppboyLogger.d(TAG, "Requesting orientation lock."); mOriginalOrientation = mActivity.getRequestedOrientation(); mActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED); } return true; } return false; }
/** * Hides any currently displaying in-app message. * * @deprecated Use {@link #hideCurrentlyDisplayingInAppMessage(boolean)} * @param animate whether to animate the message out of view. Note that in-app message animation * is configurable on the in-app message model itself and should be configured there instead. * @param dismissed whether the message was dismissed by the user. If dismissed is true, * IInAppMessageViewLifecycleListener.onDismissed() will be called on the current * IInAppMessageViewLifecycleListener. */ @Deprecated public void hideCurrentInAppMessage(boolean animate, boolean dismissed) { IInAppMessageViewWrapper inAppMessageWrapperView = mInAppMessageViewWrapper; if (inAppMessageWrapperView != null) { IInAppMessage inAppMessage = inAppMessageWrapperView.getInAppMessage(); if (inAppMessage != null) { inAppMessage.setAnimateOut(animate); } hideCurrentlyDisplayingInAppMessage(dismissed); } }
/** * Registers the in-app message manager, which will listen to and display incoming in-app * messages. The current Activity is required in order to properly inflate and display the in-app * message view. * * <p>Important note: Every Activity must call registerInAppMessageManager in the onResume * lifecycle method, otherwise in-app messages may be lost! * * @param activity The current Activity. */ public void registerInAppMessageManager(Activity activity) { AppboyLogger.d(TAG, "registerInAppMessageManager called"); // We need the current Activity so that we can inflate or programmatically create the in-app // message // View for each Activity. We cannot share the View because doing so would create a memory leak. mActivity = activity; if (mActivity != null && mApplicationContext == null) { // Note, because the IAMManager is a singleton and doesn't have any dependencies passed in, // we cache the application context here because it's not available (as it normally would be // from Appboy initialization). mApplicationContext = mActivity.getApplicationContext(); } // We have a special check to see if the host app switched to a different Activity (or recreated // the same Activity during an orientation change) so that we can redisplay the in-app message. if (mCarryoverInAppMessage != null) { AppboyLogger.d(TAG, "Requesting display of carryover in-app message."); mCarryoverInAppMessage.setAnimateIn(false); displayInAppMessage(mCarryoverInAppMessage, true); mCarryoverInAppMessage = null; } else if (mUnRegisteredInAppMessage != null) { AppboyLogger.d(TAG, "Adding previously unregistered in-app message."); addInAppMessage(mUnRegisteredInAppMessage); mUnRegisteredInAppMessage = null; } ensureSubscribedToInAppMessageEvents(mApplicationContext); }
boolean displayInAppMessage(IInAppMessage inAppMessage, boolean isCarryOver) { // Note: for mDisplayingInAppMessage to be accurate it requires this method does not exit // anywhere but the at the end // of this try/catch when we know whether we are successfully displaying the IAM or not. if (!mDisplayingInAppMessage.compareAndSet(false, true)) { AppboyLogger.d( TAG, "A in-app message is currently being displayed. Adding in-app message back on the stack."); mInAppMessageStack.push(inAppMessage); return false; } try { if (mActivity == null) { mCarryoverInAppMessage = inAppMessage; throw new Exception( "No activity is currently registered to receive in-app messages. Registering in-app message as carry-over " + "in-app message. It will automatically be displayed when the next activity registers to receive in-app messages."); } if (!isCarryOver) { long inAppMessageExpirationTimestamp = inAppMessage.getExpirationTimestamp(); if (inAppMessageExpirationTimestamp > 0) { long currentTimeMillis = System.currentTimeMillis(); if (currentTimeMillis > inAppMessageExpirationTimestamp) { throw new Exception( String.format( "In-app message is expired. Doing nothing. Expiration: $%d. Current time: %d", inAppMessageExpirationTimestamp, currentTimeMillis)); } } else { AppboyLogger.d(TAG, "Expiration timestamp not defined. Continuing."); } } else { AppboyLogger.d(TAG, "Not checking expiration status for carry-over in-app message."); } if (!verifyOrientationStatus(inAppMessage)) { throw new Exception( "Current orientation did not match specified orientation for in-app message. Doing nothing."); } IInAppMessageViewFactory inAppMessageViewFactory = getInAppMessageViewFactory(inAppMessage); if (inAppMessageViewFactory == null) { throw new Exception("ViewFactory from getInAppMessageViewFactory was null."); } final View inAppMessageView = inAppMessageViewFactory.createInAppMessageView(mActivity, inAppMessage); if (inAppMessageView == null) { throw new Exception( "The in-app message view returned from the IInAppMessageViewFactory was null. The in-app message will " + "not be displayed and will not be put back on the stack."); } if (inAppMessageView.getParent() != null) { throw new Exception( "The in-app message view returned from the IInAppMessageViewFactory already has a parent. This " + "is a sign that the view is being reused. The IInAppMessageViewFactory method createInAppMessageView" + "must return a new view without a parent. The in-app message will not be displayed and will not " + "be put back on the stack."); } Animation openingAnimation = getInAppMessageAnimationFactory().getOpeningAnimation(inAppMessage); Animation closingAnimation = getInAppMessageAnimationFactory().getClosingAnimation(inAppMessage); if (inAppMessageView instanceof IInAppMessageImmersiveView) { AppboyLogger.d(TAG, "Creating view wrapper for immersive in-app message."); IInAppMessageImmersiveView inAppMessageViewImmersive = (IInAppMessageImmersiveView) inAppMessageView; mInAppMessageViewWrapper = new InAppMessageViewWrapper( inAppMessageView, inAppMessage, mInAppMessageViewLifecycleListener, openingAnimation, closingAnimation, inAppMessageViewImmersive.getMessageClickableView(), inAppMessageViewImmersive.getMessageButtonViews(), inAppMessageViewImmersive.getMessageCloseButtonView()); } else if (inAppMessageView instanceof IInAppMessageView) { AppboyLogger.d(TAG, "Creating view wrapper for base in-app message."); IInAppMessageView inAppMessageViewBase = (IInAppMessageView) inAppMessageView; mInAppMessageViewWrapper = new InAppMessageViewWrapper( inAppMessageView, inAppMessage, mInAppMessageViewLifecycleListener, openingAnimation, closingAnimation, inAppMessageViewBase.getMessageClickableView()); } else { AppboyLogger.d(TAG, "Creating view wrapper for in-app message."); mInAppMessageViewWrapper = new InAppMessageViewWrapper( inAppMessageView, inAppMessage, mInAppMessageViewLifecycleListener, openingAnimation, closingAnimation, inAppMessageView); } mInAppMessageViewWrapper.open(mActivity); return true; } catch (Exception e) { AppboyLogger.e(TAG, "Could not display in-app message", e); resetAfterInAppMessageClose(); return false; } }