Skip to content
Last updated

Full Minimal Example (Copy/Paste)

This is a complete minimal integration. You can paste it into a clean app and it will work with Bubbl once you add your API key and Firebase config.

1) app/build.gradle.kts

plugins {
    id("com.android.application")
    id("org.jetbrains.kotlin.android")
    id("com.google.gms.google-services")
}

android {
    namespace = "com.example.mybubblapp"
    compileSdk = 34

    defaultConfig {
        applicationId = "com.example.mybubblapp"
        minSdk = 26
        targetSdk = 34
        versionCode = 1
        versionName = "1.0"
    }

    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_11
        targetCompatibility = JavaVersion.VERSION_11
    }

    kotlinOptions {
        jvmTarget = "11"
    }
}

dependencies {
    implementation(platform("com.google.firebase:firebase-bom:33.3.0"))
    implementation("com.google.firebase:firebase-messaging-ktx")
    implementation("tech.bubbl:bubbl-sdk:2.0.9")
    implementation("com.google.android.gms:play-services-location:21.2.0")
    implementation("androidx.work:work-runtime-ktx:2.10.0")
    implementation("com.google.code.gson:gson:2.10.1")
}
Dependency Set

This is the smallest reliable dependency set for Bubbl + notifications.

2) app/src/main/AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android">

    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.VIBRATE" />

    <application
        android:name=".MyApplication"
        android:allowBackup="true"
        android:label="Bubbl Demo"
        android:theme="@style/Theme.AppCompat.Light.NoActionBar">

        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <service
            android:name="tech.bubbl.sdk.services.LocationUpdatesService"
            android:foregroundServiceType="location" />

        <service
            android:name="tech.bubbl.sdk.services.MyFirebaseMessagingService"
            android:exported="false">
            <intent-filter>
                <action android:name="com.google.firebase.MESSAGING_EVENT" />
            </intent-filter>
        </service>

        <meta-data
            android:name="com.google.firebase.messaging.default_notification_channel_id"
            android:value="bubbl_push" />
    </application>
</manifest>
Background Location

You can add ACCESS_BACKGROUND_LOCATION later if you need background tracking.

3) MyApplication.kt

class MyApplication : Application() {
    override fun onCreate() {
        super.onCreate()

        if (FirebaseApp.getApps(this).isEmpty()) {
            FirebaseApp.initializeApp(this)
        }

        BubblSdk.init(
            application = this,
            config = BubblConfig(
                apiKey = "YOUR_API_KEY",
                environment = Environment.PRODUCTION,
                segmentationTags = emptyList(),
                geoPollInterval = 5 * 60_000L,
                defaultDistance = 10
            )
        )
    }
}

4) MainActivity.kt

class MainActivity : AppCompatActivity() {
    private val permMgr by lazy { PermissionManager(this) }
    private lateinit var permLauncher: ActivityResultLauncher<Array<String>>

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        permLauncher = permMgr.registerLauncher { granted ->
            if (granted) {
                BubblSdk.startLocationTracking(this)
            }
        }

        val granted = permMgr.locationGranted() &&
            (Build.VERSION.SDK_INT < 33 || permMgr.notificationGranted())

        if (granted) {
            BubblSdk.startLocationTracking(this)
        } else {
            permLauncher.launch(permMgr.requiredPermissions())
        }

        handleNotificationIntent(intent)
    }

    override fun onNewIntent(intent: Intent) {
        super.onNewIntent(intent)
        handleNotificationIntent(intent)
    }

    private fun handleNotificationIntent(intent: Intent?) {
        intent?.getStringExtra("payload")?.let { json ->
            val notification = Gson().fromJson(
                json,
                NotificationRouter.DomainNotification::class.java
            )
            ModalFragment.newInstance(notification)
                .show(supportFragmentManager, "notification_modal")
        }
    }
}
Optional Modal Handling

If you do not use modals, you can remove handleNotificationIntent and the Gson dependency.