Skip to content

Commit

Permalink
Twelfth release
Browse files Browse the repository at this point in the history
  • Loading branch information
cristidregan committed Aug 20, 2021
1 parent be41ff8 commit a4a2ce4
Show file tree
Hide file tree
Showing 21 changed files with 268 additions and 28 deletions.
12 changes: 0 additions & 12 deletions .idea/runConfigurations.xml

This file was deleted.

6 changes: 3 additions & 3 deletions OmetriaSDK/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ android {
minSdkVersion 21
targetSdkVersion 29
versionCode 1
versionName "1.1.2"
versionName "1.2.0"

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles "consumer-rules.pro"
Expand All @@ -28,8 +28,8 @@ dependencies {

// Android Core
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'androidx.core:core-ktx:1.3.2'
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.core:core-ktx:1.5.0'
implementation 'androidx.appcompat:appcompat:1.3.0'

// Lifecycle
implementation 'androidx.lifecycle:lifecycle-process:2.3.1'
Expand Down
16 changes: 14 additions & 2 deletions OmetriaSDK/src/main/java/com/android/ometriasdk/core/Ometria.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.android.ometriasdk.core

import android.app.Application
import android.app.Notification.COLOR_DEFAULT
import android.content.Intent
import android.net.Uri
import androidx.core.app.NotificationManagerCompat
Expand All @@ -26,6 +27,7 @@ import com.android.ometriasdk.core.Constants.Params.PUSH_TOKEN
import com.android.ometriasdk.core.event.EventHandler
import com.android.ometriasdk.core.event.OmetriaBasket
import com.android.ometriasdk.core.event.OmetriaEventType
import com.android.ometriasdk.core.listener.ProcessAppLinkListener
import com.android.ometriasdk.core.network.Client
import com.android.ometriasdk.core.network.ConnectionFactory
import com.android.ometriasdk.core.network.OmetriaThreadPoolExecutor
Expand Down Expand Up @@ -78,7 +80,8 @@ class Ometria private constructor() : OmetriaNotificationInteractionHandler {
fun initialize(
application: Application,
apiToken: String,
notificationIcon: Int
notificationIcon: Int,
notificationColor: Int? = COLOR_DEFAULT
) = instance.also {
it.ometriaConfig = OmetriaConfig(apiToken, application)
it.localCache = LocalCache(application)
Expand All @@ -90,7 +93,7 @@ class Ometria private constructor() : OmetriaNotificationInteractionHandler {
)
it.eventHandler = EventHandler(application, it.repository)
it.notificationHandler =
NotificationHandler(application, notificationIcon, it.executor)
NotificationHandler(application, notificationIcon, notificationColor, it.executor)
it.isInitialized = true
it.notificationInteractionHandler = instance

Expand Down Expand Up @@ -389,6 +392,15 @@ class Ometria private constructor() : OmetriaNotificationInteractionHandler {
localCache.clearEvents()
}

/**
* Retrieves the redirect url for the url that you provide.
* @param url The url that will be processed.
* @param listener The callback interface.
*/
fun processAppLink(url: String, listener: ProcessAppLinkListener) {
repository.getRedirectForUrl(url, listener)
}

override fun onDeepLinkInteraction(deepLink: String) {
Logger.d(Constants.Logger.PUSH_NOTIFICATIONS, "Open URL: $deepLink")
val intent = Intent(Intent.ACTION_VIEW)
Expand Down
30 changes: 30 additions & 0 deletions OmetriaSDK/src/main/java/com/android/ometriasdk/core/Repository.kt
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
package com.android.ometriasdk.core

import android.os.Handler
import com.android.ometriasdk.core.Constants.Logger.NETWORK
import com.android.ometriasdk.core.event.OmetriaEvent
import com.android.ometriasdk.core.event.toApiRequest
import com.android.ometriasdk.core.listener.ProcessAppLinkListener
import com.android.ometriasdk.core.network.Client
import com.android.ometriasdk.core.network.OmetriaThreadPoolExecutor
import com.android.ometriasdk.core.network.model.OmetriaApiRequest
import java.io.IOException
import java.net.HttpURLConnection
import java.net.MalformedURLException
import java.net.URL

/**
* Created by cristiandregan
Expand All @@ -21,6 +26,7 @@ internal class Repository(
private val executor: OmetriaThreadPoolExecutor
) {

private val resultHandler: Handler = Handler()
private val dropStatusCodesRange = 400..499

fun flushEvents(events: List<OmetriaEvent>, success: () -> Unit, error: () -> Unit) {
Expand Down Expand Up @@ -126,4 +132,28 @@ internal class Repository(
fun areNotificationsEnabled(): Boolean {
return localCache.areNotificationsEnabled()
}

fun getRedirectForUrl(url: String, listener: ProcessAppLinkListener) {
executor.execute {
var urlTemp: URL? = null
var connection: HttpURLConnection? = null
try {
urlTemp = URL(url)
} catch (e: MalformedURLException) {
listener.onProcessFailed(e.message ?: "Something went wrong")
}
try {
connection = urlTemp?.openConnection() as HttpURLConnection
} catch (e: IOException) {
listener.onProcessFailed(e.message ?: "Something went wrong")
}
try {
connection?.responseCode
} catch (e: IOException) {
listener.onProcessFailed(e.message ?: "Something went wrong")
}
resultHandler.post { listener.onProcessResult(connection?.url.toString()) }
connection?.disconnect()
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.android.ometriasdk.core.listener

/**
* A callback interface for processing an App Link URL.
* Processing is done async. Results will be returned on Main Thread.
*/
interface ProcessAppLinkListener {

/**
* Called when a process completes successfully.
* @param url The redirect URL resulted from process.
*/
fun onProcessResult(url: String)

/**
* Called when an exception occurs during a process.
* @param error The error message
*/
fun onProcessFailed(error: String)
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@ internal class ConnectionFactory(private val ometriaConfig: OmetriaConfig) {

fun postConnection(): HttpURLConnection {
val url = API_ENDPOINT
val requestedURL: URL
requestedURL = try {
val requestedURL: URL = try {
URL(url)
} catch (e: MalformedURLException) {
throw IOException("Attempted to use malformed url: $url", e)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,8 @@ internal class OmetriaActivityLifecycleHelper(
* Using activity started callback to track Screen View event
*/
override fun onActivityStarted(activity: Activity) {
Ometria.instance().trackAutomatedScreenViewedEvent(activity::class.simpleName)
// Disabled at clients request
// Ometria.instance().trackAutomatedScreenViewedEvent(activity::class.simpleName)
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,14 @@ const val KEY_OMETRIA = "ometria"
internal class NotificationHandler(
context: Context,
notificationIcon: Int,
notificationColor: Int?,
private val executor: OmetriaThreadPoolExecutor,
) {

private val ometriaPushNotification: OmetriaPushNotification = OmetriaPushNotification(
context,
notificationIcon
notificationIcon,
notificationColor
)

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.android.ometriasdk.notification

import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
Expand All @@ -22,7 +23,8 @@ const val OMETRIA_CHANNEL_NAME = "ometria"

internal class OmetriaPushNotification(
private val context: Context,
private val notificationIcon: Int
private val notificationIcon: Int,
private val notificationColor: Int?
) {

fun createPushNotification(
Expand All @@ -46,6 +48,7 @@ internal class OmetriaPushNotification(
.setAutoCancel(true)
.setContentIntent(contentIntent)
.setLargeIcon(image)
.setColor(notificationColor ?: Notification.COLOR_DEFAULT)

val notificationManager =
context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
Expand Down
112 changes: 112 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,31 @@ Check with the marketing team about the specifics, and what they might need. Esp
trackCustomEvent(customEventType: String, additionalInfo: Map<String, Any> = mapOf())
```

### `OmetriaBasket`

An object that describes the contents of a shopping basket.

#### Properties

* `currency`: (`String`, required) - A string representing the currency in ISO currency format. e.g. `"USD"`, `"GBP"`.
* `price`: (`float`, required) - A float value representing the pricing.
* `items`: (`Array[OmetriaBasketItem]`) - An array containing the item entries in this basket.
* `link`: (`String`) - A deeplink to the web or in-app page for this basket. Can be used ina notification sent to the user, e.g. "Forgot to check out? Here's
your basket to continue: <link>". Following that link should take them straight to the basket page.

### `OmetriaBasketItem`

An object that describes the contents of a shopping basket.

It can have its own price and quantity based on different rules and promotions that are being applied.

#### Properties

* `productId`: (`String`, required) - A string representing the unique identifier of this product.
* `sku`: (`String`, optional) - A string representing the stock keeping unit, which allows identifying a particular item.
* `quantity`: (`Int`, required) - The number of items that this entry represents.
* `price`: (`Float`, required) - Float value representing the price for one item. The currency is established by the OmetriaBasket containing this item.

### Automatically tracked events

The following events are automatically tracked by the SDK.
Expand Down Expand Up @@ -435,3 +460,90 @@ class SampleApp : Application(), OmetriaNotificationInteractionHandler {
}
}
```

7\. App links guide
----------------------------

Ometria sends personalised emails with URLs that point back to your website. In order to open these URLs inside your application, make sure you follow this guide.

### Pre-requisites

First, make sure you have an SSL-enabled Ometria tracking domain set up for your account. You may already have this for
your email campaigns, but if not ask your Ometria contact to set one up, and they should provide you with the domain.

### Handle App Links inside your application

To add Android App Links to your app, define intent filters that open your app content using HTTP URLs. Intent filters for incoming links
will be added inside your **AndroidManifest** file, the following XML snippet is an example (assuming "clickom.omdemo.net" is the tracking domain):

```xml
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />

<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />

<data
android:host="clickom.omdemo.net"
android:scheme="https" />
</intent-filter>
```

This will ensure that when your customers click on links in Ometria emails, your app opens instead of the browser.

**Note:** This does not associate your website's domain with the app, only the tracking domain.

Find more about Android App Links [here](https://developer.android.com/training/app-links/verify-site-associations).

### Create a digital asset links JSON file and send it to your Ometria contact.

The Digital Asset Links JSON file is used to create a relationship between a domain and your app. [You can find more info about it here](https://developer.android.com/training/app-links/verify-site-associations#web-assoc).
A basic example should look like this:

```javascript
[
{
"relation": [ "delegate_permission/common.handle_all_urls" ],
"target": {
"namespace": "android_app",
"package_name": "com.android.sample",
"sha256_cert_fingerprints": ["51:5B:24:4B:C7:A4:7F:D2:FA:B2:C7:23:73:7A:A0:91:A5:B6:29:49:08:73:E1:51:7E:CF:60:28:53:65:47:25"]
}
}
]
```

Save it and name it "assetlinks.json". Then send it to your Ometria contact - we will upload this for you so that it will be available behind the
tracking domain.

### Process App Links inside your application

The final step is to process the URLs in your app and take the user to the appropriate sections of the app. Note that
you need to implement the mapping between your website's URLs and the screens of your app.

See also [Linking push notifications to app screens](https://support.ometria.com/hc/en-gb/articles/4402644059793-Linking-push-notifications-to-app-screens).

If you are dealing with normal URLs pointing to your website, you can decompose it into different path components and parameters. This will allow you to source the required information to navigate through to the correct screen in your app.

However, Ometria emails contain obfuscated tracking URLs, and these need to be converted back to the original URL, pointing to your website, before you can map the URL to an app screen. To do this, the SDK provides a method called `processAppLink`:

```kotlin
private fun handleAppLinkFromIntent() {
// you can check here whether the URL is one that you can handle without converting it back
intent.dataString?.let { url ->
Ometria.instance().processAppLink(url, object : ProcessAppLinkListener {
override fun onProcessResult(url: String) {
// you can now handle the retrieved url as you would any other url from your website
}

override fun onProcessFailed(error: String) {
// an error may have occurred
}
})
}
}
```

**Warning**: The method above runs asynchronously. Depending on the Internet speed on the device, processing time can vary. For best results, you could implement a loading state that is displayed while the URL is being processed.

If you have done everything correctly, the app should now be able to open app links and allow you to handle them inside the app.
6 changes: 3 additions & 3 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,10 @@ dependencies {

// Support libraries
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'androidx.core:core-ktx:1.3.2'
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.core:core-ktx:1.5.0'
implementation 'androidx.appcompat:appcompat:1.3.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation 'com.google.android.material:material:1.4.0-beta01'
implementation 'com.google.android.material:material:1.4.0-rc01'

// Add the SDK for Firebase Cloud Messaging
implementation 'com.google.firebase:firebase-messaging:22.0.0'
Expand Down
11 changes: 11 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,17 @@

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />

<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />

<data
android:host="clickom.omdemo.net"
android:scheme="https" />
</intent-filter>

</activity>

<activity
Expand Down
4 changes: 3 additions & 1 deletion app/src/main/java/com/android/sample/SampleApp.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import android.app.Application
import android.content.Intent
import android.net.Uri
import android.util.Log
import androidx.core.content.ContextCompat
import com.android.ometriasdk.core.Ometria
import com.android.ometriasdk.notification.OmetriaNotificationInteractionHandler

Expand All @@ -26,7 +27,8 @@ class SampleApp : Application(), OmetriaNotificationInteractionHandler {
Ometria.initialize(
this,
"YOUR_API_TOKEN",
R.mipmap.ic_launcher
R.drawable.ic_notification_nys,
ContextCompat.getColor(this, R.color.colorAccent)
).loggingEnabled(true)

// Set the notificationInteractionDelegate in order to provide actions for
Expand Down
Loading

0 comments on commit a4a2ce4

Please sign in to comment.