๐ Flutter
The bbb_meeting_sdk plugin opens the meeting full-screen on top of the Flutter view and hands control back, with the leave reason, when the user leaves. No React Native or Expo in your project: the meeting client ships as the prebuilt native SDKs (Android AAR, iOS XCFrameworks), which your build downloads.
| Package | bbb_meeting_sdk 0.1.0 on pub.dev |
| Requirements | Flutter 3.44 or later (built and tested with Flutter 3.47 on Android and iOS); iOS builds need Xcode 26.x, as for the native iOS SDK |
๐ฆ 1. Installโ
flutter pub add bbb_meeting_sdk
Then apply the Android and iOS host settings below.
๐ป 2. Usageโ
import 'package:bbb_meeting_sdk/bbb_meeting_sdk.dart';
await BbbMeetingSdk.initialize(); // optional warm-up
final sub = BbbMeetingSdk.events.listen((event) { /* BbbJoinedEvent, BbbLeftEvent, BbbErrorEvent */ });
final left = await BbbMeetingSdk.join(BbbJoinOptions(joinUrl: url, meetingName: 'Weekly'));
// completes when the user is back: left.reason is left | ended | error | unsupported | cancelled
// while the meeting is open (for example from a timer): await BbbMeetingSdk.leave();
BbbJoinOptions also carries theme, pictureInPicture, screensharePresenter, embedMode, largeScreenLayout and devLogging. BbbSdkConfig, passed as initialize(config: โฆ), carries clientType and appVersion. All options are in the ๐ API reference.
Instead of opening a meeting, join throws a PlatformException:
| Code | When |
|---|---|
already_in_meeting | a meeting is already open |
invalid_arguments | no join URL was given |
no_activity / no_view_controller | there is nothing to present the meeting from |
join_failed | (Android) the SDK cannot start the meeting |
initialize throws no_application on Android when there is no application context yet.
๐ค 3. Android host appโ
The plugin's own Gradle file adds the SDK's Maven repository, pins fbjni 0.7.0, ships R8 keep rules for the SDK and swaps the debug variants of react-android / hermes-android for their release AARs (a debug flutter run would otherwise crash at startup). What stays in your app, in android/app/build.gradle.kts:
android {
defaultConfig {
minSdk = 24
// The SDK ships 64-bit libraries only. The Flutter Gradle plugin has already filled abiFilters
// with armeabi-v7a, arm64-v8a and x86_64, so `+=` alone would keep armeabi-v7a: clear it first.
ndk {
abiFilters.clear()
abiFilters += listOf("arm64-v8a", "x86_64")
}
}
packaging {
// react-android and fbjni both ship these
jniLibs { pickFirsts += listOf("**/libc++_shared.so", "**/libfbjni.so") }
}
buildTypes {
release {
// Flutter minifies release builds; the SDK is not R8-safe (its native code looks classes up by
// name). The plugin's keep rules are best effort: keep minification off for now.
isMinifyEnabled = false
isShrinkResources = false
}
}
}
- The SDK's AAR (about 88 MB) carries the permissions, the meeting activity (
BbbMeetingActivity, single task, picture-in-picture) and the foreground service: nothing to add toAndroidManifest.xml. - Use
compileSdk36 and Java 17. - Check the result:
unzip -l build/app/outputs/flutter-apk/app-release.apk | grep armeabishould print nothing. A 32-bitarmeabi-v7afolder would hold an incomplete set of libraries and crash on 32-bit devices. Don't combine the filter with--split-per-abi. - Gradle downloads the AAR from the SDK's Maven repository. To use a mirror or a local copy, set
bbbSdkMavenUrl=<url>inandroid/gradle.properties. - Play Console: declare the foreground-service use cases microphone, media playback and media projection.
Build release (flutter build apk --release, flutter run --release): the SDK is built from release React Native libraries. Debug builds rely on the plugin's variant rule, which has not been exercised yet.
๐ 4. iOS host appโ
- Set the Runner's minimum deployment target to iOS 16.4 (Xcode: Runner โ General โ Minimum Deployments, or
IPHONEOS_DEPLOYMENT_TARGET = 16.4inios/Runner.xcodeproj). Flutter raises its generated package to match. - Info.plist:
NSMicrophoneUsageDescription,NSCameraUsageDescription,NSBluetoothAlwaysUsageDescription,NSBluetoothPeripheralUsageDescription,NSLocalNetworkUsageDescription,NSPhotoLibraryUsageDescription,NSPhotoLibraryAddUsageDescription,UIBackgroundModes=audio,UIViewControllerBasedStatusBarAppearance=false(the meeting UI drives the status bar through React Native; without it the calls are no-ops that log an error on every join), and optionallyio.livekit.reactnative.expo.ENABLE_MULTITASKING_CAMERA_ACCESS=true(the camera keeps running in picture-in-picture where iOS allows it). - Frameworks: the SDK's XCFrameworks are about 230 MB of zips, downloaded once and checked against pinned SHA-256 checksums. With Swift Package Manager (Flutter's default) the plugin depends on the SDK's Swift package, same version as the plugin. With CocoaPods (SwiftPM disabled), the first
pod installruns the plugin'sios/fetch_frameworks.sh, which downloads the same zips; useplatform :ios, '16.4'. - Screen sharing from the device needs a Broadcast Upload Extension in your app (๐ฅ๏ธ iOS screen sharing); pass
screensharePresenter: trueonly then.
๐งช Exampleโ
The plugin's example/lib/main.dart is one screen with a join URL field, a Join meeting button and a log of the SDK events. In a new app (flutter create), apply the host settings above, add the package and use that file as lib/main.dart:
flutter run --release --dart-define=BBB_JOIN_URL='https://<server>/html5client/join?sessionToken=<token>'