Skip to main content

Android SDK Setup Guide With Octopus Authentication


Install the SDK

Octopus is available on Maven Central. Add the dependencies to your build.gradle file:

dependencies {
// Core SDK functionnalities
implementation("com.octopuscommunity:octopus-sdk:x.x.x")
// SDK UI Components (optional)
implementation("com.octopuscommunity:octopus-sdk-ui:x.x.x")
}

See the Octopus SDK GitHub Release section to get the latest published version.


Use the SDK

As early as possible in your code, you should initialize the OctopusSDK object.

This object is expecting two things:

  • the Octopus Community API key
  • the connection mode
warning

You are reading the Octopus Authentication connection mode documentation, if your community is configured to use SSO, please open the documentation for this mode.

Call the OctopusSDK initialization function in your Application's onCreate() block:

class YourApplication : Application() {

override fun onCreate() {
super.onCreate()

OctopusSDK.initialize(
context = this, // Application Context
apiKey = "YOUR_API_KEY"
)
}
}

If you want to enhance the user experience, Octopus SDK lets you pass a deep link that will be called right after that the user has opened the magic link. This means that when you pass a deeplink, your app will be immediatly put in foreground, keeping your users focused on what they were doing before the connection.

To do that, simply initialize the SDK this way:

OctopusSDK.initialize(
context = this, // Application Context
apiKey = "YOUR_API_KEY",
deepLinksBasePaths = listOf("https://www.example.com/octopus")
)
note

If not done yet, you will also have to add an intent filter for the URL scheme included in your deeplink. See the Android documentation to know more about it.


Display the Octopus Community UI

Now that you have the SDK properly configured, you can add a button in your app that opens the Octopus Community UI.

Integrate Octopus composables navigation

Add the Octopus SDK composables to your navigation graph.

This function registers multiple composable() destinations in your NavGraphBuilder for the entire Octopus SDK navigation flow.

  1. Add the Octopus composables to your navigation graph within your actual NavHost:

    val navController = rememberNavController()

    NavHost(navController) {
    composable<...> {
    }

    octopusComposables(navController = navController)
    }
  2. Then, either:

    Embed the OctopusHomeContent or OctopusHomeScreen in your composable
    NavHost(...) {
    composable<Community> {
    Box {
    OctopusTheme(...) {
    OctopusHomeContent(
    modifier = Modifier.fillMaxSize(),
    navController = navController
    )
    }
    }
    }

    octopusComposables(...)
    }

    OR

    Simply navigate to the Octopus Home route
    navController.navigate(OctopusDestination.Home)

Modify the theme

The Octopus SDK lets you modify its theme so its UI looks more like yours.

You can modify:

  • the colors:
    • the primary colors (a main color, a low contrast and a high contrast variations of the main color). Please note that the high contrast variation of the primary color is not used for the moment. If you do not pass a custom value for it, black/white default values will be used.
    • the color of the elements (mostly texts) displayed over the primary color. If you do not pass a custom value for it, white/black default value will be used.
  • the fonts. You can customize the styles (title1, body2, caption1...) used in the sdk. If you do not pass a custom value for it, default value will be used.
  • the logo. This is an image displayed on the Octopus home page and profile creation view. If you do not pass a custom image for it, Octopus logo value will be used.
  • the TopAppBar. You can customize the appearance, title, navigation icons, actions, and colors of the TopAppBar. If you do not pass a custom configuration for it, default TopAppBar will be used.

By default, Octopus will rely on your Application's MaterialTheme.colorScheme but you can customize the UI more precisely by surrounding composables with the OctopusTheme:

To do that, you can override the theme by passing it as environment object:

octopusComposables(
navController = navController,
container = { backStackEntry, content ->
OctopusTheme(
colorScheme = if (isSystemInDarkTheme()) {
octopusDarkColorScheme(
primary = yourDarkPrimaryColor, // Default: MaterialTheme.colorScheme.primary
primaryLow = lowContrastVersionOfYourPrimaryColor, // Default: MaterialTheme.colorScheme.primaryContainer
primaryHigh = highContrastVersionOfYourPrimaryColor, // Default: MaterialTheme.colorScheme.inversePrimary
onPrimary = yourDarkOnPrimaryColor, // Default: MaterialTheme.colorScheme.onPrimary
background = yourDarkBackgroundColor // Default: MaterialTheme.colorScheme.background
// See the complete list in the sources documentation
)
} else {
octopusLightColorScheme(
primary = yourLightPrimaryColor, // Default: MaterialTheme.colorScheme.primary
primaryLow = lowContrastVersionOfYourPrimaryColor, // Default: MaterialTheme.colorScheme.primaryContainer
primaryHigh = highContrastVersionOfYourPrimaryColor, // Default: MaterialThème.colorScheme.inversePrimary
onPrimary = yourLightOnPrimaryColor, // Default: MaterialTheme.colorScheme.onPrimary
background = yourLightBackgroundColor // Default: MaterialTheme.colorScheme.background
// See the complete list in the sources documentation
)
},
typography = OctopusTypographyDefaults.typography(
title1 = yourCustomTitle1Style, // Default: TextStyle(fontSize = 26.sp)
title2 = yourCustomTitle2Style // Default: TextStyle(fontSize = 22.sp)
// See the complete list in the sources documentation
),
drawables = OctopusDrawablesDefaults.drawables(
logo = painterResource(R.drawable.your_custom_logo), // Default: R.drawable.ic_octopus_logo
tint = yourLogoTintColor // Default: null (no image tinting)
),
topAppBar = OctopusTopAppBarDefaults.topAppBar(
title = { text ->
OctopusTopAppBarTitle(
text = text,
textStyle = yourCustomTitleStyle
)
},
colors = OctopusTopAppBarDefaults.colors(
containerColor = yourTopAppBarBackgroundColor,
contentColor = yourTopAppBarContentColor
)
// See the complete list in the sources documentation
)
) {
content()
}
}
)

All parameters of the Theme have default values. Only override the ones that you want to customize. On the following example, you are creating an OctopusTheme with default colors, default fonts except for the title1 and a custom logo:

OctopusTheme(
typography = OctopusTypographyDefaults.typography(
title1 = TextStyle(fontFamily = FontFamily.SansSerif, fontSize = 24.sp)
),
drawables = OctopusDrawablesDefaults.drawables(
logo = painterResource(R.drawable.your_custom_logo)
)
) {
OctopusHomeScreen(...)
}

Here is a summary of the impacts of the theme you choose: Light Mode Dark Mode

Here is a summary of the text styles used in the main screens of the SDK: Text Styles

Customize the TopAppBar

You can customize the appearance of the TopAppBar in the Octopus SDK screens by providing your own OctopusTopAppBar configuration when setting up the theme. We highly encourage you to choose a short text title (less than 18 characters).

OctopusTheme(
topAppBar = OctopusTopAppBarDefaults.topAppBar(
title = { text ->
OctopusTopAppBarTitle(
text = "Your TopAppBar Title", // Default: text
logo = OctopusDrawable(painterResource(R.drawable.your_logo)), // Default: OctopusTheme.drawables.logo
textStyle = yourTopAppBarTextStyle // Default: LocalTextStyle.current
)
},
colors = OctopusTopAppBarDefaults.colors(
containerColor = yourTopAppBarBackgroundColor, // Default: OctopusTheme.colorScheme.background
contentColor = yourTopAppBarContentColor // Default: OctopusTheme.colorScheme.gray900
),
navigationIcon = { type, onClick ->
IconButton(onClick = onClick) {
Icon(
imageVector = when (type) {
NavigationIconType.Back -> YourBackIcon
NavigationIconType.Close -> YourCloseIcon
},
contentDescription = when (type) {
NavigationIconType.Back -> "Navigate back"
NavigationIconType.Close -> "Close"
}
)
}
}
// See the complete list in the sources documentation
)
)
info

The OctopusTopAppBar will automatically use your theme's color scheme if no specific colors are provided, ensuring consistency across your app.

Advanced Screen-Based Theming

For more complex theming scenarios, you can customize any aspect of the Octopus theme (colors, typography, drawables, TopAppBar) based on the current screen:

octopusComposables(
navController = navController,
container = { backStackEntry, content ->
OctopusTheme(
colorScheme = when {
// Post Details with branded theme
backStackEntry.destination.hasRoute<OctopusDestination.PostDetails>() -> {
octopusColorScheme().copy(
background = if (isSystemInDarkTheme()) Color.Black else Color.White
)
}
else -> octopusColorScheme()
},
topAppBar = when {
// Home screen with custom TopAppBar theme
backStackEntry.destination.hasRoute<OctopusDestination.Home>() -> {
OctopusTopAppBarDefaults.topAppBar(
title = { text ->
OctopusTopAppBarTitle(text = "My Community")
}
)
}
else -> OctopusTopAppBarDefaults.topAppBar()
}
) {
content()
}
}
)

Push Notifications ≥ 1.4.0

To increase user engagement, you can provide informations to the Octopus SDK so your users can receive push notifications when other users interact with them inside the community.

note

Octopus SDK is not asking for push notification permissions, we let you handle that part where it makes more sense in your app.

If your app does not support Push Notifications yet, you can follow the official Firebase documentation.

Our servers need your service account's private key file to be authorized to send notifications to your app on your behalf.

If you don't have this JSON file yet, follow this tutorial
  • In the Firebase console, open Settings > Service Accounts
  • Click Generate New Private Key, then confirm by clicking Generate Key.
  • Securely store the JSON file containing the key.

More information can be found in the official Firebase documentation

Please send the json file using the online form sent by the Octopus team.

warning

This JSON file is different from the one you are using to configure Firebase in your app (google-services.json)

Once your project is correctly setup for push notifications, you should forward the Firebase Cloud Messaging Token (FCM Token) to the Octopus SDK:

class MessagingService : FirebaseMessagingService() {
override fun onNewToken(token: String) {
super.onNewToken(token)

// Register the new token with Octopus
OctopusSDK.registerNotificationsToken(token)
}
}
note
You are in charge of requesting the Notification permission and referencing your messaging service
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
if (checkSelfPermission(POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) {
// Request launcher for notification permission
registerForActivityResult(
contract = ActivityResultContracts.RequestPermission(),
callback = {
FirebaseMessaging.getInstance().token.addOnCompleteListener { task ->
if (task.isSuccessful) {
OctopusSDK.registerNotificationsToken(task.result)
}
}
}
).launch(POST_NOTIFICATIONS)
}
<service
android:name=".notifications.MessagingService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>

When you receive a notification message, first check if it is an Octopus notification by calling:

override fun onMessageReceived(remoteMessage: RemoteMessage) {
super.onMessageReceived(remoteMessage)

val isOctopusNotification = remoteMessage.data.isOctopusNotification
if(isOctopusNotification) {
...
}
}

If it's the case, display the Octopus Notification using the Notification Manager:

val octopusNotification = OctopusSDK.getOctopusNotification(data = remoteMessage.data)
if(octopusNotification != null) {
notificationManager.notify(
octopusNotification.id,
NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_stat_notification)
.setColor(getColor(R.color.accent))
.setAutoCancel(true)
.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
// Extension function to extract the title, text and deep link from the OctopusNotification
.setOctopusContent(
context = this,
activityClass = MainActivity::class,
octopusNotification = octopusNotification
).build()
)
}
note
  • The activityClass must be the one containing the compose content with the octopusNavigation() subgraph.
  • The setOctopusContent function is based on a deep link mechanism that will automatically launch the activity and navigate to the corresponding screen within the Octopus Navigation graph.
  • You can also handle the content manually by using the OctopusNotification's title, body and linkPath fields and configuring your own PendingIntent.

Not seen notifications ≥ 1.3.0

To increase user engagement, let your users know that they have new notifications from the Octopus notification center. Displaying a badge with the number of new notifications in your app can be a great way to suggest your users to look at what's new in the community again.

To do that, the Octopus SDK exposes a val notSeenNotificationsCount: Flow<Int> that you can collect:

OctopusSDK.notSeenNotificationsCount.collect {}

If you want to update this value with the latest count, simply call:

OctopusSDK.updateNotSeenNotificationsCount()

To see a full example of how you can achieve that, you can follow how it is done in the Samples, in the octopus-auth/fullscreen app.


Analytics

Octopus Community provides analytics to help you better understand your users' behavior within the community. To improve the quality of these analytics, we offer features that allow you to provide additional information about your users.

Custom events ≥ 1.4.0

You can tell the SDK to register a custom event. This event can be merged into the reports we provide.

OctopusSDK.track(
event = TrackerEvent.Custom(
name = "Purchase",
properties = mapOf(
"price" to TrackerEvent.Custom.Property(
value = String.format(Locale.US, "%.2f", 1.99)
),
"currency" to TrackerEvent.Custom.Property(value = "EUR"),
"product_id" to TrackerEvent.Custom.Property(value = "product1")
)
)
)

Configure Community Visibility ≥ 1.3.0

If you enable access to the community for only a subset of your users and want the analytics we provide to take this into account, you can inform the SDK accordingly.

This information is reset at each SDK launch so be sure to call the function everytime and as soon as possible after SDK init.

OctopusSDK.setHasAccessToCommunity(canAccessCommunity)

Follow the Samples

Want to see a code examples on how to use the SDK, no worries, we have that for you!

  1. First, clone the OctopusSDK project

    Android SDK

  1. Add this line to the root project local.properties file:

    OCTOPUS_API_KEY=YOUR_API_KEY

    Replace YOUR_API_KEY with your own API key.

  2. Run the samples.octopus-auth.fullscreen or samples.octopus-auth.embed app depending on your needs.