zello 0.1.1 copy "zello: ^0.1.1" to clipboard
zello: ^0.1.1 copied to clipboard

Flutter plugin wrapping the native Zello Work Mobile SDKs (Android/iOS) for push-to-talk, voice RX/TX, text messaging, channels and presence.

zello — Flutter plugin for the Zello Work Mobile SDKs #

A Flutter plugin that wraps the native Zello Work Mobile SDKs (Android Kotlin, iOS Swift) and exposes a clean, idiomatic Dart API for:

  • Push-to-talk (works with the screen off / app in background)
  • Channel connect / disconnect with auto-reconnect events
  • Voice TX (start/stopTalking) and RX (incoming voice start/stop events)
  • Text messages
  • Presence / status
  • Hardware PTT buttons and Apple PushToTalk integration on iOS

There is no official Zello Flutter SDK — this package is a community platform-channel wrapper around the official native SDKs.

Installation #

dependencies:
  zello: ^0.1.0
import 'package:zello/zello.dart';

Quick start #

await Zello.instance.initialize(
  config: const ZelloConfig(appKey: '<your-zello-sdk-key>'),
);

final sub = Zello.instance.events.listen((event) {
  // event is a sealed ZelloEvent – switch on its subtypes
});

await Zello.instance.connect(
  network: 'mycompany.zellowork.com',
  token: jwtFromYourBackend, // RS256, short-lived
);

// PTT button pressed
await Zello.instance.startTalking('dispatch');
// PTT button released
await Zello.instance.stopTalking();

Public Dart API #

Member Purpose
Zello.initialize({required ZelloConfig config}) One-time native init.
connect({required String network, required String token, String? username}) Connect to a Zello Work network with a short-lived JWT.
disconnect() Disconnect. Idempotent.
startTalking(String channel) Begin TX. Wire to PTT press.
stopTalking() End TX. Wire to PTT release.
sendTextMessage(String channel, String text) Send a text message.
setStatus(ZelloStatus status) Update presence.
getChannelState(String channel)ZelloChannel Snapshot of a channel.
events Stream<ZelloEvent> (broadcast).
connectionState ValueListenable<ZelloConnectionState> for UI.
dispose() Tear down native resources.

All native failures surface as ZelloException(code, message, details). Events are a sealed Dart-3 hierarchy — switch exhaustively over ZelloConnectionStateChanged, ZelloIncomingVoiceStarted/Stopped, ZelloOutgoingTalkStateChanged, ZelloIncomingTextMessage, ZelloChannelStatusChanged, ZelloReconnectAttempt, ZelloErrorEvent, ZelloUnknownEvent.

Setup & Native SDK Installation #

The Zello Mobile SDKs are gated behind a Zello Work subscription and cannot be redistributed via this repo. You must obtain them yourself and wire them in.

1. Obtain the SDK artifacts #

  1. Sign in to your Zello Work admin portal.
  2. Provision an SDK key for your app.
  3. Download:
    • Android: AAR or Maven coordinates of the Zello Channels SDK.
    • iOS: XCFramework (or CocoaPods coordinate, if your subscription ships one).

2. Android wiring #

In android/build.gradle.kts of this plugin (already scaffolded):

allprojects {
    repositories {
        google()
        mavenCentral()
        maven { url = uri("https://maven.zello.com/release") } // example
    }
}

dependencies {
    implementation("com.zello:zello-channel-sdk:<version>")
    // or, for a local AAR:
    // implementation(files("libs/zello-channel-sdk.aar"))
}

The plugin already declares (in android/src/main/AndroidManifest.xml):

  • RECORD_AUDIO
  • FOREGROUND_SERVICE, FOREGROUND_SERVICE_MICROPHONE
  • POST_NOTIFICATIONS (Android 13+)
  • BLUETOOTH_CONNECT (for headset PTT discovery)
  • MODIFY_AUDIO_SETTINGS, WAKE_LOCK, INTERNET, ACCESS_NETWORK_STATE
  • A foreground service ZelloForegroundService with android:foregroundServiceType="microphone" so PTT keeps working with the screen off.

You must request the runtime permissions in your host app (RECORD_AUDIO, POST_NOTIFICATIONS, BLUETOOTH_CONNECT) using permission_handler or your tool of choice before calling connect().

Then wire the real Zello SDK calls inside android/src/main/kotlin/com/zello/flutter/ZelloSdkAdapter.kt — every TODO in that file is a single SDK call (one line typically). The channel plumbing (ZelloPlugin.kt) does not need to change.

3. iOS wiring #

In ios/zello.podspec (already scaffolded), uncomment one of:

# CocoaPods
s.dependency 'ZelloChannelKit', '~> 1.0'

# Or vendored XCFramework
# s.vendored_frameworks = 'Frameworks/ZelloSDK.xcframework'

In the host app's ios/Runner/Info.plist add:

<key>NSMicrophoneUsageDescription</key>
<string>Used for push-to-talk voice.</string>
<key>UIBackgroundModes</key>
<array>
  <string>audio</string>
  <string>push-to-talk</string>
</array>

In the host app's Runner.entitlements add:

<key>com.apple.developer.push-to-talk</key>
<true/>

…and enable the Push to Talk capability in Xcode (Signing & Capabilities). Without that entitlement, PT calls will fail silently — set enableApplePushToTalk: false in ZelloConfig if you cannot get the entitlement yet (background PTT will then be limited).

The plugin already configures AVAudioSession for playAndRecord / .voiceChat / .allowBluetooth / .defaultToSpeaker.

Wire the real Zello iOS SDK calls inside ios/Classes/ZelloSdkAdapter.swift — same pattern as Android, every TODO is one SDK call.

4. Backend token minting (auth) #

The plugin only accepts a short-lived JWT (RS256) in connect(token:). It must never see the issuer private key.

Your backend should:

  1. Hold the Zello issuer + RS256 private key in a secret store.
  2. Mint a JWT per user / per session with a short expiry (e.g. 60–120 s).
  3. Return the JWT to the app over HTTPS.

The Flutter app simply receives the token and passes it to connect().

Threading & lifecycle #

  • All MethodChannel.Result and EventSink calls are dispatched on the platform main thread (Handler(Looper.getMainLooper()) on Android, DispatchQueue.main on iOS).
  • The plugin holds a single native client per Flutter engine. dispose() cancels native listeners, tears down the session, and stops the Android foreground service.
  • Auto-reconnect attempts from the native SDK are surfaced as ZelloReconnectAttempt events — never swallowed.

Manual device-test checklist #

The unit tests cover the Dart layer with a mocked MethodChannel. The native voice path must be exercised on real hardware:

  1. Connect on Android, lock the screen, press PTT (button or wired) — TX audio reaches the channel; foreground-service notification is visible.
  2. Receive a transmission while the app is backgrounded — RX audio plays through the speaker / Bluetooth headset.
  3. Kill network connectivity for 10 s, restore — ZelloReconnectAttempt then ZelloConnectionStateChanged(connected) arrive in Dart.
  4. iOS: with the PTT entitlement, background PTT keeps working and the system PTT UI appears in Control Center.
  5. iOS: route audio to a Bluetooth headset — AVAudioSession switches without dropping the session.
  6. Hardware PTT button on a Sonim/Crosscall device triggers start/stopTalking.
  7. Send/receive a text message; verify ZelloIncomingTextMessage.
  8. setStatus(ZelloStatus.busy) — other Zello clients see the new status.

Known limitations / TODO #

  • All Zello SDK symbol references are placeholders behind ZelloSdkAdapter (Android + iOS). Replace the // TODO: confirm against Zello SDK vX blocks with the real SDK calls from your Zello Work portal. The channel layer does not need to change.
  • Image messages, location messages, and direct (1:1) voice are not yet exposed in the Dart API.
  • Channel user-list streaming is not yet exposed; only getChannelState(channel) snapshots.
  • Hardware PTT button auto-routing on Android relies on the Zello SDK's built-in handling; custom HID key mapping is not implemented here.
  • The iOS Apple-PushToTalk delegate (ApplePTTBridge) implements the minimum required methods; extend as you wire real Zello TX/RX.
  • No federated split (single-package). If/when this plugin gains macOS or web support, splitting into platform interface + implementations would be appropriate.
  • The example app's android/ and ios/ projects are not committed — run flutter create --platforms=android,ios . inside example/ once, then build.
0
likes
160
points
--
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Flutter plugin wrapping the native Zello Work Mobile SDKs (Android/iOS) for push-to-talk, voice RX/TX, text messaging, channels and presence.

Repository (GitHub)
View/report issues

License

MIT (license)

Dependencies

flutter, meta

More

Packages that depend on zello

Packages that implement zello