Adding the Notification Plugin
Preserve Flutter and JNA classes
In the proguard-rules.pro
file make sure that the Flutter and JNA classes are preserved to avoid any exceptions with missing plugins or classes.
# Preserve Flutter Wrapper code
-keep class io.flutter.app.** { *; }
-keep class io.flutter.plugin.** { *; }
-keep class io.flutter.util.** { *; }
-keep class io.flutter.view.** { *; }
-keep class io.flutter.** { *; }
-keep class io.flutter.plugins.** { *; }
-keep class io.flutter.plugin.editing.** { *; }
# JNA
-keep class com.sun.jna.** { *; }
-keep class * implements com.sun.jna.** { *; }
# To ignore minifyEnabled: true error
# https://github.com/flutter/flutter/issues/19250
# https://github.com/flutter/flutter/issues/37441
-dontwarn io.flutter.embedding.**
-ignorewarnings
-keep class * {
public private *;
}
Adding the SDK dependency
Add the maven jitpack
repository to your project build.gradle
file.
allprojects {
repositories {
maven { url 'https://www.jitpack.io' }
}
}
Add the breez-sdk-liquid
dependency to your application's build.gradle
file in the app
directory.
android {
defaultConfig {
// Add a build config field to read the Breez API key
// from a git ignored `gradle.properties` file
buildConfigField "String", "BREEZ_SDK_API_KEY", project.property('BREEZ_SDK_API_KEY')
}
// This might help building if duplicate libraries are found
packagingOptions {
pickFirst "lib/armeabi-v7a/libc++_shared.so"
pickFirst "lib/arm64-v8a/libc++_shared.so"
pickFirst "lib/x86/libc++_shared.so"
pickFirst "lib/x86_64/libc++_shared.so"
exclude "META-INF/*"
}
}
dependencies {
// Add the breez-sdk-liquid dependency
implementation "com.github.breez:breez-sdk-liquid"
}
Integrate the Notification Plugin
You're ready to add some Kotlin code to implement the Notification Plugin in your application. In the example below, we are using the FirebaseMessagingService
to receive the message intents. First, let's implement the Notification Plugin's MessagingService
class along with FirebaseMessagingService
.
package com.example.application
import android.annotation.SuppressLint
import android.content.Intent
import androidx.core.content.ContextCompat
import breez_sdk_liquid_notification.Constants
import breez_sdk_liquid_notification.Message
import breez_sdk_liquid_notification.MessagingService
import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage
@SuppressLint("MissingFirebaseInstanceTokenRefresh")
class ExampleFcmService : MessagingService, FirebaseMessagingService() {
companion object {
private const val TAG = "FcmService"
}
// Override the `onMessageReceived` to handle the remote message
override fun onMessageReceived(remoteMessage: RemoteMessage) {
super.onMessageReceived(remoteMessage)
// Check if the message is high priority and can be handled
if (remoteMessage.priority == RemoteMessage.PRIORITY_HIGH) {
remoteMessage.asMessage()?.also { message ->
// Call `startServiceIfNeeded` to check if the foreground
// service is needed depending on the message type and
// foreground state of the application
startServiceIfNeeded(applicationContext, message)
}
}
}
// A helper function the convert the `RemoteMessage`
// to a notification plugin 'Message'
private fun RemoteMessage.asMessage(): Message? {
return data[Constants.MESSAGE_DATA_TYPE]?.let {
Message(
data[Constants.MESSAGE_DATA_TYPE], data[Constants.MESSAGE_DATA_PAYLOAD]
)
}
}
// Override the `startForegroundService` function to start the foreground service
// using the `ExampleForegroundService` handler
override fun startForegroundService(message: Message) {
val intent = Intent(applicationContext, ExampleForegroundService::class.java)
intent.putExtra(Constants.EXTRA_REMOTE_MESSAGE, message)
ContextCompat.startForegroundService(applicationContext, intent)
}
}
Now lets add the foreground service implementation. This should implement the notification plugin ForegroundService
class, which handles the incoming notification intent and processes the event. To properly implement this, your class needs to override the onCreate
, getConnectRequest
and getServiceConfig
functions. The getConnectRequest
function is called by the ForegroundService
to get a ConnectRequest
which contains the data necessary to connect to the SDK. This data includes the Breez API key, the Config
with it's workingDir
and the mnemonic.
Developer note
In Android reading from secured storage can vary a lot depending if it is a Kotlin, Flutter or React Native based application and the dependencies used to write to the secured storage. Consult the dependency used to write to the secured storage on how to read data back from them.package com.example.application
import breez_sdk_liquid.ConnectRequest
import breez_sdk_liquid.defaultConfig
import breez_sdk_liquid.LiquidNetwork
import breez_sdk_liquid_notification.ForegroundService
import breez_sdk_liquid_notification.NotificationHelper.Companion.registerNotificationChannels
import com.example.application.BuildConfig
class ExampleForegroundService : ForegroundService() {
companion object {
private const val TAG = "ForegroundService"
private const val ACCOUNT_MNEMONIC = "BREEZ_SDK_LIQUID_SEED_MNEMONIC"
}
// Override the `onCreate` function
override fun onCreate() {
super.onCreate()
// Register the default notification channels
registerNotificationChannels(applicationContext)
}
// Override the `getConnectRequest` function
override fun getConnectRequest(): ConnectRequest? {
// Get the Breez API key from the build config
val apiKey = BuildConfig.BREEZ_SDK_API_KEY
val config = defaultConfig(LiquidNetwork.MAINNET, apiKey)
// Set the workingDir as the same directory as the main application
config.workingDir = "${applicationContext.filesDir}/breezSdkLiquid"
// Get the mnemonic from secured storage using an implementation of
// `readSecuredValue` depending on how data is written to secured storage.
// See Developer Note
return readSecuredValue(applicationContext, ACCOUNT_MNEMONIC)
?.let { mnemonic ->
ConnectRequest(config, mnemonic)
}
}
}
Reference implementation
For a complete reference, see how we implemented it in misty-breez wallet: BreezFcmService.kt.