27.01.20234.1.6Dependency Update:
androidx.appcompat:appcompat from 1.5.1 to 1.6.0
org.altbeacon:android-beacon-library from 2.19.4 to 2.19.5
com.google.firebase:firebase-messaging from 23.1.0 to 23.1.1
androidx.test:runner from 1.5.1 to 1.5.2
androidx.test.ext:junit from 1.1.4 to 1.1.5

Improvements:
1. In App will retry to show every 5 secs, max 10 times. After around 1 min the In App will not be retried anymore and an IN_APP_BOUNCED event will be triggered.
2. getPulsateDaggerComponent() renamed to getDI() - helps shorten code and makes code more readable.
3. getInbox() errors will now properly be logged and shown in logcat.
4. In Apps rework - Moving from RxJava to Coroutines, moving In App Flow logic into "tryToShowInAppMessage" - this makes it easier to follow the flow and find possible bug, collecting stats for In Apps simplified - moved some logic into "tryToShowInAppMessage".
5. Start session will retry 5 times before failing - this retries the "if/else" conditions needed to start a session not the network call itself.
6. uncaughtExceptions will now check if stacktrace contains "pulsatehq" before sending the crash to New Relic.
7. Fixed getUserData() when there is no current user set. getUserData() will now use getActiveUserAlias() which creates a default user if there is no current user. This fixes PulsateUserManagerTests.
8. Stats for pushes and in apps will be unique per session.
9. PulsateUploadAndDeleteNewRelic - optimizing code.

Crash Fixes:
1. Crash Fix - Deleting the last item in the inbox will no longer crash.
2. Crash Fix - createDynamicView - will now check if "attrsList" is before casting to protect from any possible chance of a crash.
3. Crash Fix - Beacons monitoring can be updated 1 time per minute. When multiple updates happen in a row the next update will wait 1 minute before applying any changes.
4. Crash Fix - SecurityException - Notifications now require a permission the user can deny, calling .notify to show a push without checking the permission can cause a crash. Added SecurityException try / catch to all .notify calls.
5. Crash Fix - PulsateFeedViewModel IndexOutOfBoundsException - PulsateFeedViewModel will now use synchronized(mFeedState) when doing any changes to the mFeedState and it's lists.
6. Crash Fix - PulsateBeaconManager IndexOutOfBoundsException - PulsateBeaconManager will now use synchronized(mAllPulsateBeacons) when doing any changes to the mAllPulsateBeacons list.
7. Fixed crash - Feed IndexOutOfBoundsException.
8. Fixed crash - Null Pointer binding.
9. Fixed crash - Null Pointer In App Point.
10. Fixed crash - ClassCastException - PulsateCardViewHolder will now check if frontElementAttrs IS before casting it.
11. Fixed crash - IllegalArgumentException: You cannot start a load for a destroyed activity - Glide will now use application context when loading images into PulsateBigInApp.

Bug Fixes:
1. Deleting the last item in the inbox will properly animate.
2. Added missing else statements to when brackets.
3. PulsateCardAttrsSerializer - when type is unknown we will now return PulsateEmptyAttrsDTO.
4. PulsateCardAttrsDeserializer - when type is unknown we will now return PulsateEmptyAttrsDTO.
5. Fixed - Feed Display issues - no internet connection message displayed on feed loading screen. Added a 5sec delay after connection network changes before sending connection network errors to give the device time to potentially recover from a short connection loss.
6. Fixed - Feed Display issues - Bottom of feed continuously loading instead of displaying you have reached the bottom of the feed. PulsateFeedItemLoading and PulsateFeedItemEnd now have unique guids and different types, this fixes PulsateFeedDiffUtilCallback and RecyclerView updates.
7. Fixed bug in PulsateInboxViewModel mPulsateUserDataLiveData - LiveData setValue called from outside main thread.
17.11.20224.1.0In Apps:
- showLastInAppNotification() changed to showLastInAppNotification(force: Boolean = false) - Shows the last in app notification that was blocked due to setInAppNotificationEnabled(FALSE) being called. The force variable by default is FALSE, if you set it to TRUE the SDK will ignore some checks and will try to force the In App to display. For example when force is true the In App will show even if setInAppNotificationEnabled(FALSE) was called and In Apps are disabled.
- Will now fail early if they are empty or null.
- Added new retry disposable Timer. The disposable will be disposed to make sure there is only one retry job running for In Apps at any time.
- ShowInAppMessageDisposable will now be disposed to make sure there is only one show job running for In Apps at any time.
- Will retry when they IN_APP_BOUNCE is registered.
- In App retry limit increased to 10.

New features:
- New classes - IPulsateErrorListener & PulsateError - All SDK errors will be pushed to this listener for Developers to be able to log / debug / react to them. Currently only supports In Apps. setPulsateErrorListener(listener: IPulsateErrorListener) added to IPulsateManager.

Improvements:
- Implemented KSP for Room and Glide.
- Added exception: Exception variable to PulsateError class.
- PulsateErrors will now be sent to New Relic.
- PulsateUserDao rewritten to use Coroutines instead of RxJava.
- PulsateSettingsDao started rewrite to use Coroutines instead of RxJava.

Bug Fixes:
- Removed PulsateAppDatabase encryption - Encryption used CWAC SafeRoom which was deprecated years ago and no longer works properly with Kotlin and Room.

Tests:
- Added tests for all PulsateUserManager methods related to changing user data.
- PulsatePrivacy - added value: String used for tests.
- PulsateGender - added value: String used for tests.
- PulsateRoomMigrationTest - tests migration from version 7 to 8 and version 8 to 13.
26.10.20224.0.3Improvements
- The badge count will now be tracked locally when possible and will send updates to IPulsateBadgeUpdateListener in real time. When a user clicks on a campaign that is unread we set it to read and reduce the badge by 1, when a users clicks on a talk that has unread messages we set the talk to read and reduce the badge by the amount of messages that were unread.
- Read / Unread state will be tracked locally, multiple Feed refreshes should always show the proper state.


Bug Fixes
- Fixed sending push_click stats for talks. This fixes a possible 500 error when sending stats to the BE.


Others
- Dependency updates.
- Code cleanup using ktlint.
29.09.20224.0.0Major Changes
- The SDK has been rewritten to Kotlin.
- Target SDK changed to 33.
- New permission required - POST_NOTIFICATIONS.
- Dependency update. For more info please read this article - https://docs.pulsatehq.com/v2.8.2/reference/dependencies


New Features
- Android badges will now be supported. For more info please read this article - https://docs.pulsatehq.com/v2.8.2/reference/android-badges
- Crash logging. The SDK will now log crashes caused by the Pulsate SDK and send them to Pulsate.


Improvements
- forceAttributeSync() will now be delayed by 5 secs and will combine all calls to forceAttributeSync() into one.
- Orientation change will no longer cause the Feed and Threads to redownload items.
- Removing BroadcastReceivers, jobs will now directly do their work.
- Removed EventBus.
- Requests will now retry 3 times if API Access Token is not generated before failing a request.
- Reworked how API Access Tokens are generated.
- Improved Database synchronization when used from multiple threads.
- Improved PulsateProvider synchronization when used from multiple threads.
- Fixed multiple Feed bugs caused by orientation change.


Geofencing
- Reduced the amount of location updates done by the SDK.
- Improved goefence accuracy.


Beacons
- Changed exit period to 30 secs to reduce the amount of false exits.


In Apps
- In Apps will no longer show up multiple times when changing screen orientation or leaving the App.
- Added additional checks to In Apps to prevent multiple In Apps to be drawn.


Bug Fixes
- Pulsate Feed will now work better on screen orientation change.
- Added security checks to dagger. Will now only ever create a single instance.
- Fixed multiple issues that could cause daily jobs to never run.
- Fixed Toolbar to properly take the full width on Foldables, Tablets, Chromebooks.
- Fixed showing messages that were blocked for unauthorized users.
- Fixed opening the proper destination when opening multiple push notifications at a time.


Crash Fixes
- Fixed crashes caused by process death or app recreation.
- Fixed a crash caused by ProcessLifecycleOwner.
05.12.20223.8.2Improvements:
- Backported some In App Improvements from 4.1.0.

In Apps
- showLastInAppNotification() changed to showLastInAppNotification(force: Boolean = false) - Shows the last in app notification that was blocked due to setInAppNotificationEnabled(FALSE) being called. The force variable by default is FALSE, if you set it to TRUE the SDK will ignore some checks and will try to force the In App to display. For example when force is true the In App will show even if setInAppNotificationEnabled(FALSE) was called and In Apps are disabled.
- In Apps will no longer be deleted after retry ends.
13.01.20223.8.1Improvements:
- Converted Workers to CoroutineWorkers.


Bug Fixes:
- Added missing tryOnError() and onComplete() callbacks to BroadcastReceivers.
- Fixed WorkerManager crash pre API 31 - setExpedited() isn't enough, we also needed to provide ForegroundInfo. The documentation doesn't make this very obvious, and there's no API enforcement.
15.12.20213.8.0Important Changes:
- Added Android 12 Support
- Added Accessibility Support


Breaking Changes:
- Set minSdkVersion to 23 (Android 6.0).
- New Permissions required for beacons
android.permission.BLUETOOTH
android.permission.BLUETOOTH_ADMIN
android.permission.BLUETOOTH_SCAN
android.permission.BLUETOOTH_CONNECT


Improvements
- Added Kotlin. The SDK will be totally rewritten to Kotlin in the next releases.
- Added the possibility to remotely enable / disable debug mode and send logs to Firebase.
- Fixed geofences and beacons on Android 12.
- Updated to newest WorkManager, added expedited jobs.
- Moved some work done by the SDK from the main thread to the io thread.


In App Rework:
Improvements:
- In Apps will now survive activity swaps.
- Added In App validation. If the In App fields are not valid the In App will not show.
- Added In App retry. After an In App fails to show it will retry 3 times.
- Added new In App event - in_app_error.
- Added Logs.

Bug Fixes:
- Fixed possible scaling issue for big In Apps.
- In Apps will now close the keyboard before showing. The keyboard could cause scaling issues.


Beacon Rework:
Important!!
New Permissions required for beacons
android.permission.BLUETOOTH
android.permission.BLUETOOTH_ADMIN
android.permission.BLUETOOTH_SCAN
android.permission.BLUETOOTH_CONNECT

Improvements:
- Added Support for Android 12.
- Updated AltBeacon Library to version 2.19.3 - Fix failing intent-backed scans broken by Android 12 changes in the 2.19 release.
- Reworked beacon event sync. The chain for syncing is now - Directly -> Broadcast Receiver -> Background Job.
- Added Logs.

Bug Fixes:
- Fixed saving beacons to database. Previously beacons could get deleted when startSession would happen without data.


Geofence Rework:
Improvements:
- Added Android 12 support.
- Reworked geofence event sync. The chain for syncing is now - Directly -> Broadcast Receiver -> Background Job.
- Added Logs.

Bug Fixes:
- Fixed saving geofences to database. Previously geofences could get deleted when startSession would happen without data.


Notification Rework:
Improvements:
- Replying to a Pulsate Notification will now send the reply, inform the user the reply was sent successfully and delete the notification.
- Added Logs.

Bug Fixes:
- Fixed possible crash when the user receives multiple notifications to the same card / talk.


Bug Fixes:
- Removed com.google.android.geo.API_KEY from SDK.
- Fixed crashes in In App and Card when attrs for front elements are empty.
- Fixed crash - java.lang.IllegalStateException: schedule()/enqueue() called more than 250 times in the past 60000ms.
- Fixed crash- Work Manager IllegalStateException - WorkManager will now try to getInstance, on fail it will try to create a WorkManager with custom config, on fail it will return null and not schedule a job.
- Fixed possible crashes caused by sending error events to no longer active emitters.
18.06.20213.7.1SDK Distribution:
JFrog has shut down JCenter and Bintray. The Pulsate SDK will now be distributed using MavenCentral.
To download the newest versions of Pulsate you must be connected to MavenCentral. Current versions of the Pulsate SDK on MavenCentral can be found here - https://mvnrepository.com/artifact/com.pulsatehq.sdk/PulsateSdk


Breaking Changes:
- Set minSdkVersion to 21 (Android 5.0).


New Features:
- Stats - the SDK will now gather stats from pushes, in apps, cards and send them to the server to allow showing advanced campaign stats.
- Test Mode - added new Pulsate Test Mode. During Test Mode the SDK will show a notification that the SDK is in Test Mode, clicking on the notification will take the user to the Test Mode UI, where the user can view geofence logs, beacons logs, network logs and send all logs to Pulsate Developers.


Improvements:
- Reworked end session logic to work better on devices that are overly aggressive with killing / blocking Apps from doing any work in the background.
- Big In Apps - improved scaling and appear animation on multiple devices.
- Added collecting background_location_permission.
- Updated / Removed many dependencies.
- Code cleanup.


Bug Fixes:
- Fixed possible crash when gathering user actions.
- Fixed showing .jpeg images in Rich Push Notifications.
- Fixed edge cases where the SDK would not clear data after sending it to the server.
- Fixed possible leaks introduced in Android 10.
25.11.20203.6.0Improvements:
- Fixed a lot of warnings reported by Code Inspect.
- Fixed possible memory leaks.
- Proguard rules cleanup.
- Layouts cleanup.
- Deprecated FirebaseInstanceId replaced with FirebaseMessaging
- Removed 24h restriction on downloading geofences and beacons. Start Session will now always download geofences and beacons


Bug Fixes:
- Pulsate BeaconManager will now try to catch all exceptions and handle them silently in the SDK.
- Notification Channels will be created on App onCreate() callback instead of creating them in the FCM onNewToken() callback.
- Removed setIntent(null); from PulsateInboxActivity this should fix an issue where unauthorized intent wasn't properly set.
12.11.20203.5.01. New Features
- Feed title text size can now be changed. To change the text size add "pulsate_feed_title" to your dimens.xml.
- Card button colors can now be changed. To change add "pulsate_card_left_btn_color", "pulsate_card_right_btn_color", "pulsate_card_single_btn_color" to your colors.xml

2. Improvements:
- Replace databinding with viewbinding.
- Updated Firebase to newest versions - firebase-core:18.0.0, firebase-messaging:21.0.0
- Updated many dependencies to newest versions.
- Updated to newest Gradle version.
- Removed limits for Admin message in In App Messages and Pulsate cards. The SDK would limit Admin message to 2-4 lines while the CMS would not have any limits.

3. Bug Fixes:
- Fixed showing In App Notifications for unauthorized users.
- Fixed crash in PulsateBeaconManager when beacon identifiers are broken. The SDK will now ignore beacons that are not properly setup.
- Fixed crash when user minimizes App when on the back of a card and clicks on a push notification that opens a new card.
13.10.20203.4.31. Bug Fixes:
- Fixed method - showLastInAppNotification().
05.10.20203.4.21. Bug Fixes:
- Crash Fix - Fixed crash that happens when unauthorized users enter the Pulsate Inbox
01.09.20203.4.11. New Features:
- New method - updatePhoneNumber() - Updates the user's phone number. Gets updated when entering background.
- Implemented Screen Recording - the SDK will automatically track what screens of the App the user visits.


2. Improvements:
- Database - Less DB actions need to take place per update. Fixed a possible concurrency issue.
- Broadcasts - will be handled with LocalBroadcastManager. This makes sure broadcasts stay within the App and are not System wide. This also fixes very rare crashes on some phones.
- Updated dependencies.
Git stats.


3. Bug Fixes:
- Fixed possible crash in Pulsate Feed.
01.07.20203.3.11. Bug Fixes:
- Improved scaling images in In App Notifications.
- Improved scaling images in Feed Cards.
10.06.20203.3.01. New Features:
- New method - getFeed(int page, IPulsateValueListener listener).
- New method - handleFeedClick(PulsateInboxItem pulsateInboxItem, int destination).
- New Method - initializeBackgroundPowerSaver() - Initializes the Beacon Background Power Saver Mode. This mode can save up to 60% of battery in the background. Exit events can happen almost instantly, but depending on device / OS version in can take up to 15 mins to trigger an exit.


2. Improvements:
- Updated Gradle to version 4.0.0.
- Update Android Studio to version 4.0.0.
PulsateBeaconManager code cleanup.
- Removed background optimizations for beacons. This makes exit events more responsive. Apps that don't use Background exit events can turn on the background battery saver using the new method - initializeBackgroundPowerSaver()
- Improved App Foreground / Background checks.


3. Bug Fixes:
- Now properly only the first page of the Feed will be cached. The bug would cause next pages to overwrite previous pages.
- Single Card Feed now properly works after pausing the App. Before if the user paused the App while in single Card Feed the view would stop reacting to clicks.
- Added missing ReentrantLock unblock to start session.
- Crash Fix - fixed possible In App Notification Crash.
16.04.20203.2.01. New Features:
- Added Revenue Events which allow you to track event name, event value and event currency. More info can be found here - https://pulsate.readme.io/v2.8/docs/setting-custom-events#revenue-events


2. Bug Fixes:
- Fixed possible crashes in Broadcast Receivers when PendingResult is null.
- Fixed possible crash in PulsateCardFrontFragment when Activity is null.
- Added a possible fix to possible crashes when Database queries end with an Error and the Observable asking for the data has already been disposed.
08.04.20203.1.01. Breaking Changes:
- Pulsate.install() removed. Pulsate.install() has been deprecated in previous builds and should no longer be used. Pulsate now automatically installs.
- Removed Microfencing methods from PulsateManager since Microfencing is not used in the SDK.
- startSession will now download Geofence and Beacon data only once per day.
- Beacons and Geofences are now set to be active for 1 hour, so any events within that time frame will be labeled as duplicates.
- When testing the SDK set PulsateDebugLogs.LOG_LOCATION_MANAGER = true. This causes startSession to download data every time and allows Beacons and Geofences to be triggered every 5mins. Do not use this in release builds. This can slow down the SDK, increase the amount of data uploaded and downloaded by the SDK and increase it's size over time because Logs are gathered and saved in the SDK Database.


2. Geofencing Changes:
- Geofence events will now be sent immediately, if the event fails a PulsateJob will be registered to retry within 15mins. Events that return 404 Not Found will not be retried.
- There can be more than one active geofence now and all of them will be separately monitored. This change can help us filter out false positives.
- Geofence events now use "Triggering Location" from the "GeofencingEvent" received from the system instead of trying to scan for the user location.
- Added many fallbacks to location checks. The SDK will first try to do a location scan, on fail it will ask Fused Location for last known location, on fail it will use the last SDK known location.


3. Beacon Changes:
- Updated to AltBeacon 2.16.4 which fixes a possible crash when scanning in background and improves discovering beacons on Samsung devices.
- Beacon events will now be sent immediately, if the event fails a PulsateJob will be registered to retry within 15mins. Events that return 404 Not Found will not be retried.
- Beacon events will now be filtered by UUID, Major and Minor on SDK side to not send to the server beacon events for beacons that don't exist server-side.
- Foreground scan periods changed to help filter out possible false positives and reduce battery usage.
- BeaconManager will now be set to BackgroundMode when the App is closed. BackgroundMode reduces the amount of scans happening to save battery.
- Implemented BackgroundPowerSaver. BackgroundPowerSaver will help reduce battery usage on many devices.
- Removed beacon ranging. The SDK will now rely on beacon monitoring which should work better in the background and reduce power usage.
- Fixed possible race condition when adding and removing beacons.


4. Bug Fixes:
- Fixed a bug that could cause Feed Cards to not be deleted after a user manually deleted them.
- Fixed a bug that could cause startPulsateSession to sometimes call onSuccess 2 times.
- Fixed a possible crash when PendingResult is null in the Geofence / Beacon BroadcastReceiver.
- Fixed a posbbile crash when getting FCM Token from Firebase.
- Fixed a bug that could cause the Database to desync.
- Fixed possible Database race conditions in User Settings and SDK Settings.


5. Misc:
- Added some missing getters to PulsateManager.
- Updated some dependncies.


6. Test:
- Improved test coverage for PulsateManager methods, User Settings, SDK Settings, Location, Geofecing, Beacons, Database.
29.01.20203.0.41. Removed bluetooth_state checks and request.
2. Renamed mContext to mApplication in places where the context was the application context.
3. Moved some layouts into subdirectories.
22.01.20203.0.31. Fixed possible Firebase / FCM crash. Firebase / FCM will now fail silently if it encounters any problems without crashing the App.
2. When Firebase fails the FCM token will be set to an empty string and startSession will happen normally instead of not happening at all.
3. Glide will now show a stack trace when it fails to load an image into a notification.
4. In App Notifications will check if activity is changing configuration or is finishing before showing.