Skip to content

Commit

Permalink
Updating Android SDK to version 24.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
radixdev committed Jan 4, 2023
1 parent 3f6d22f commit 443b232
Show file tree
Hide file tree
Showing 195 changed files with 1,711 additions and 1,341 deletions.
34 changes: 34 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,37 @@
## 24.0.0

[Release Date](https://github.com/Appboy/appboy-android-sdk/releases/tag/v24.0.0)

#### Breaking
- Location and geofence functionality has moved to a new module called `com.braze:android-sdk-location`. Add this module to your `build.gradle` if you are using Braze location functionality.
- Deprecated classes starting with `Appboy` have now been removed.
- Moved `com.appboy` packages to `com.braze`.
- All xml classes and values in them have been changed from `appboy` to `braze`. All custom code should be updated accordingly.
- `BrazeNotificationUtils.isAppboyPushMessage()` removed. Please use instead:
- Java: `BrazeNotificationUtils.isBrazePushMessage(Intent)`
- Kotlin: `Intent.isBrazePushMessage()`
- `APPBOY_NOTIFICATION_OPENED_SUFFIX`, `APPBOY_NOTIFICATION_RECEIVED_SUFFIX`, and `APPBOY_NOTIFICATION_DELETED_SUFFIX` are removed.
- Instead, please use `Braze.getInstance(context).subscribeToPushNotificationEvents()`
- Updated the minimum version of `com.google.android.gms:play-services-location` required for Braze Geofences to `20.0.0`.

##### Added
- Added the ability to optionally pipe Braze logcat from `BrazeLogger` to a custom callback via `BrazeLogger.onLoggedCallback`.
```kotlin
BrazeLogger.onLoggedCallback = fun(priority: BrazeLogger.Priority, message: String, throwable: Throwable?) {
// Custom callback logic here
}
```
```java
BrazeLogger.setOnLoggedCallback((priority, s, throwable) -> {
// Custom logic here
return null;
});
```

##### Changed
- Removed `BrazeUser.setFacebookData()` and `BrazeUser.setTwitterData()`.
- Changed the default behavior of `DefaultContentCardsUpdateHandler` to use the creation time vs last update time when sorting Content Cards.

## 23.3.0

[Release Date](https://github.com/Appboy/appboy-android-sdk/releases/tag/v23.3.0)
Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Copyright (c) 2022 Braze, Inc.
Copyright (c) 2023 Braze, Inc.
All rights reserved.

* Use of source code or binaries contained within Braze’s SDKs is permitted only to enable use of the Braze platform by customers of Braze.
Expand Down
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ Successful marketing automation is essential to the future of your mobile app. B

- `android-sdk-base` - the Braze SDK base analytics library.
- `android-sdk-ui` - the Braze SDK user interface library for in-app messages, push, and the news feed.
- `android-sdk-location` - the Braze SDK location library for location and geofences.
- `droidboy` - a sample app demonstrating how to use Braze in-depth.
- `android-sdk-unity` - a library that enables Braze SDK integrations on Unity.
- `samples` - a folder containing several sample apps for various integration options.
Expand All @@ -39,7 +40,8 @@ allprojects {

```
dependencies {
implementation 'com.appboy:android-sdk-ui:23.3.+'
implementation 'com.appboy:android-sdk-ui:24.0.+'
implementation 'com.appboy:android-sdk-location:24.0.+'
...
}
```
Expand All @@ -58,7 +60,7 @@ repositories {

```
dependencies {
implementation 'com.appboy:android-sdk-ui:23.3.+'
implementation 'com.appboy:android-sdk-ui:24.0.+'
}
```

Expand Down
31 changes: 31 additions & 0 deletions android-sdk-location/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'

dependencies {
api "com.appboy:android-sdk-base:${BRAZE_SDK_VERSION}"
compileOnly "androidx.annotation:annotation:${ANDROIDX_ANNOTATIONS_VERSION}"
implementation "org.jetbrains.kotlin:kotlin-stdlib:${KOTLIN_VERSION}"
implementation "com.google.android.gms:play-services-location:${PLAY_SERVICES_LOCATION_VERSION}"
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:${KOTLIN_COROUTINES_VERSION}")
implementation "androidx.core:core:${ANDROIDX_CORE_VERSION}"
}

android {
compileSdkVersion rootProject.ext.compileSdkVersion
buildToolsVersion rootProject.ext.buildToolsVersion

defaultConfig {
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
}

kotlinOptions {
freeCompilerArgs = ['-Xjvm-default=all', '-Xopt-in=kotlin.RequiresOptIn']
jvmTarget = "1.8"
}

compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
10 changes: 10 additions & 0 deletions android-sdk-location/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.appboy.location">
<application>
<receiver
android:name="com.braze.location.BrazeActionReceiver"
android:exported="false">
</receiver>
</application>
</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
package com.braze.location

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.location.Location
import android.location.LocationManager
import android.os.Build
import androidx.annotation.Keep
import androidx.annotation.VisibleForTesting
import com.braze.BrazeInternal
import com.braze.Constants
import com.braze.enums.GeofenceTransitionType
import com.braze.models.outgoing.BrazeLocation
import com.braze.support.BrazeLogger.Priority.E
import com.braze.support.BrazeLogger.Priority.W
import com.braze.support.BrazeLogger.brazelog
import com.google.android.gms.location.Geofence
import com.google.android.gms.location.GeofencingEvent
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch

@Keep
class BrazeActionReceiver : BroadcastReceiver() {
@OptIn(DelicateCoroutinesApi::class)
override fun onReceive(context: Context?, intent: Intent?) {
if (intent == null) {
brazelog(W) { "BrazeActionReceiver received null intent. Doing nothing." }
return
} else if (context == null) {
brazelog(W) { "BrazeActionReceiver received null context. Doing nothing." }
return
}
val applicationContext = context.applicationContext
// This pending result allows us to perform work off the main thread and receive 10 seconds from the system
// to finish processing. By default, a BroadcastReceiver is allowed 5 seconds (due to the ANR limit)
// for processing.
val pendingResult = goAsync()
val actionReceiver = ActionReceiver(applicationContext, intent)

GlobalScope.launch(Dispatchers.IO) {
actionReceiver.run()
pendingResult.finish()
}
}

@VisibleForTesting
internal class ActionReceiver(
private val applicationContext: Context,
private val intent: Intent
) {
private val action: String? = intent.action
fun run() {
try {
performWork()
} catch (e: Exception) {
// If the action receiver encounters an error, we still have to mark the broadcast receiver's work as finished.
brazelog(E, e) {
"Caught exception while performing the BrazeActionReceiver work. Action: $action Intent: $intent"
}
}
}

/**
* Performs the work as specified by the intent action.
*
* @return True iff the work was perform successfully.
*/
@VisibleForTesting
fun performWork() {
brazelog { "Received intent with action $action" }
when (action) {
null -> {
brazelog { "Received intent with null action. Doing nothing." }
}
Constants.BRAZE_ACTION_RECEIVER_GEOFENCE_UPDATE_INTENT_ACTION -> {
brazelog { "BrazeActionReceiver received intent with geofence transition: $action" }
GeofencingEvent.fromIntent(intent)?.let { handleGeofenceEvent(applicationContext, it) }
}
Constants.BRAZE_ACTION_RECEIVER_SINGLE_LOCATION_UPDATE_INTENT_ACTION -> {
brazelog { "BrazeActionReceiver received intent with single location update: $action" }
val location = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
intent.extras?.getParcelable(LocationManager.KEY_LOCATION_CHANGED, Location::class.java)
} else {
@Suppress("DEPRECATION")
intent.extras?.get(LocationManager.KEY_LOCATION_CHANGED) as Location?
}
location?.let { handleSingleLocationUpdate(applicationContext, it) }
}
else -> {
brazelog(W) { "Unknown intent received in BrazeActionReceiver with action: $action" }
}
}
}

companion object {
private fun handleSingleLocationUpdate(applicationContext: Context, location: Location): Boolean {
try {
BrazeInternal.logLocationRecordedEvent(applicationContext, BrazeLocation(location))
} catch (e: Exception) {
brazelog(E, e) { "Exception while processing single location update" }
return false
}
return true
}

/**
* Records all geofence transitions in the given geofence event.
*
* @param applicationContext The application context
* @param geofenceEvent Google Play Services geofencing event
* @return true if a geofence transition was recorded
*/
@VisibleForTesting
fun handleGeofenceEvent(applicationContext: Context, geofenceEvent: GeofencingEvent): Boolean {
if (geofenceEvent.hasError()) {
val errorCode = geofenceEvent.errorCode
brazelog(W) { "Location Services error: $errorCode" }
return false
}

val transitionType = geofenceEvent.geofenceTransition
val triggeringGeofences = geofenceEvent.triggeringGeofences
return when {
Geofence.GEOFENCE_TRANSITION_ENTER == transitionType -> {
triggeringGeofences?.forEach { geofence ->
BrazeInternal.recordGeofenceTransition(
applicationContext,
geofence.requestId,
GeofenceTransitionType.ENTER
)
}
true
}
Geofence.GEOFENCE_TRANSITION_EXIT == transitionType -> {
triggeringGeofences?.forEach { geofence ->
BrazeInternal.recordGeofenceTransition(
applicationContext,
geofence.requestId,
GeofenceTransitionType.EXIT
)
}
true
}
else -> {
brazelog(W) { "Unsupported transition type received: $transitionType" }
false
}
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package com.braze.location

import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import com.braze.Constants
import com.braze.models.BrazeGeofence
import com.braze.support.IntentUtils
import com.google.android.gms.location.LocationServices

/**
* An implementation of the geofence calls so that they are contained in a single, external
* module that clients don't need to include if they don't want location services.
*/
class BrazeInternalGeofenceApi : IBrazeGeofenceApi {

/**
* @return the PendingIntent that should be fired when a geofence is triggered.
*/
override fun getGeofenceTransitionPendingIntent(context: Context): PendingIntent {
val geofenceIntent = Intent(Constants.BRAZE_ACTION_RECEIVER_GEOFENCE_UPDATE_INTENT_ACTION)
.setClass(context, BrazeActionReceiver::class.java)
val flags = PendingIntent.FLAG_UPDATE_CURRENT or IntentUtils.getMutablePendingIntentFlags()
return PendingIntent.getBroadcast(context, 0, geofenceIntent, flags)
}

/**
* Teardown all geofences associated with the given intent.
*/
override fun teardownGeofences(applicationContext: Context, intent: PendingIntent) {
LocationServices.getGeofencingClient(applicationContext)
.removeGeofences(intent)
}

/**
* Register a list of geofences.
*
* @param context Application context.
* @param geofenceList List of [BrazeGeofence] to be registered.
* @param geofenceRequestIntent The intent to fire when geofence is triggered.
*/
override fun registerGeofences(
context: Context,
geofenceList: List<BrazeGeofence>,
geofenceRequestIntent: PendingIntent
) {
GooglePlayLocationUtils.registerGeofencesWithGooglePlayIfNecessary(context, geofenceList, geofenceRequestIntent)
}

/**
* Deletes the geofence cache.
*/
override fun deleteRegisteredGeofenceCache(context: Context) {
GooglePlayLocationUtils.deleteRegisteredGeofenceCache(context)
}
}
Loading

0 comments on commit 443b232

Please sign in to comment.