flutter_zoom_sdk_advanced 0.1.0 copy "flutter_zoom_sdk_advanced: ^0.1.0" to clipboard
flutter_zoom_sdk_advanced: ^0.1.0 copied to clipboard

A Flutter plugin for Zoom Meeting SDK with support for joining meetings, email login, meeting controls, and real-time meeting events.

example/lib/main.dart

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_zoom_sdk_advanced/flutter_zoom_sdk_advanced.dart';
import 'package:permission_handler/permission_handler.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Zoom SDK Example',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        colorSchemeSeed: const Color(0xFF2D8CFF),
        useMaterial3: true,
        brightness: Brightness.light,
      ),
      home: const ZoomExamplePage(
        // JWT token from server
        jwtToken: '',
        zakToken: null,
        // USER_ZAK_TOKEN_FROM_BACKEND (For Zoom org users)
        joinToken: "",
        // USER_JOIN_TOKEN_FROM_BACKEND (For external registered users)
      ),
    );
  }
}

class ZoomExamplePage extends StatefulWidget {
  final String jwtToken;
  final String? zakToken;
  final String? joinToken;

  const ZoomExamplePage({
    super.key,
    required this.jwtToken,
    this.zakToken,
    this.joinToken,
  });

  @override
  State<ZoomExamplePage> createState() => _ZoomExamplePageState();
}

class _ZoomExamplePageState extends State<ZoomExamplePage> {
  final _zoomPlugin = FlutterZoomSdkAdvanced();
  String _status = 'Initializing...';
  bool _sdkInitialized = false;
  bool _sdkInitFailed = false;
  bool _joining = false;
  StreamSubscription? _eventSubscription;

  final _meetingIdController = TextEditingController();
  final _meetingPasswordController = TextEditingController();
  final _displayNameController = TextEditingController(text: 'Flutter User');

  @override
  void initState() {
    super.initState();
    _initSdk();
  }

  Future<void> _initSdk() async {
    setState(() {
      _status = 'Initializing...';
      _sdkInitFailed = false;
    });
    final result = await _zoomPlugin.initZoom(ZoomOptions(
      jwtToken: widget.jwtToken,
    ));
    final success = result['status'] == true;
    if (!mounted) return;
    setState(() {
      _sdkInitialized = success;
      _sdkInitFailed = !success;
      _status = success ? 'Ready' : result['message']?.toString() ?? 'Init failed';
    });
    if (success) {
      _eventSubscription = _zoomPlugin.onMeetingStateChanged().listen((event) {
        if (!mounted) return;
        final status = event['status']?.toString() ?? '';
        debugPrint('[ZoomSDK] Dart event: $status');
        if (status.contains('ENDED') || status.contains('IDLE')) {
          setState(() => _joining = false);
        }
      });
    }
  }

  Future<void> _joinMeeting() async {
    final meetingId = _meetingIdController.text.trim();
    final password = _meetingPasswordController.text.trim();
    final name = _displayNameController.text.trim();

    if (meetingId.isEmpty || name.isEmpty) {
      _showSnackBar('Meeting ID and Display Name are required');
      return;
    }

    final cameraStatus = await Permission.camera.request();
    final micStatus = await Permission.microphone.request();
    if (!cameraStatus.isGranted || !micStatus.isGranted) {
      if (!mounted) return;
      _showSnackBar('Camera and microphone permissions are required');
      return;
    }

    setState(() => _joining = true);
    debugPrint('[ZoomSDK] Dart joinMeeting - id: $meetingId, hasZak: ${widget.zakToken != null}, hasJoinToken: ${widget.joinToken != null}');
    if (widget.joinToken != null) {
      debugPrint('[ZoomSDK] joinToken length: ${widget.joinToken!.length}, starts with: ${widget.joinToken!.substring(0, widget.joinToken!.length > 20 ? 20 : widget.joinToken!.length)}...');
    }
    final result = await _zoomPlugin.joinMeeting(ZoomMeetingOptions(
      meetingId: meetingId,
      meetingPassword: password,
      displayName: name,
      zakToken: widget.zakToken,
      joinToken: widget.joinToken,
    ));

    debugPrint('[ZoomSDK] Dart join result: $result');
    if (!mounted) return;
    final success = result['status'] == true;
    if (!success) {
      setState(() => _joining = false);
      _showSnackBar(result['message']?.toString() ?? 'Failed to join');
    }
  }

  void _showSnackBar(String message) {
    ScaffoldMessenger.of(context)
      ..clearSnackBars()
      ..showSnackBar(SnackBar(
        content: Text(message),
        behavior: SnackBarBehavior.floating,
        shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
      ));
  }

  @override
  void dispose() {
    _eventSubscription?.cancel();
    _meetingIdController.dispose();
    _meetingPasswordController.dispose();
    _displayNameController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);

    return Scaffold(
      backgroundColor: theme.colorScheme.surface,
      body: SafeArea(
        child: Center(
          child: SingleChildScrollView(
            padding: const EdgeInsets.symmetric(horizontal: 24),
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                // Logo / Header
                Container(
                  width: 80,
                  height: 80,
                  decoration: BoxDecoration(
                    color: theme.colorScheme.primaryContainer,
                    borderRadius: BorderRadius.circular(20),
                  ),
                  child: Icon(
                    Icons.videocam_rounded,
                    size: 40,
                    color: theme.colorScheme.primary,
                  ),
                ),
                const SizedBox(height: 16),
                Text(
                  'Join Meeting',
                  style: theme.textTheme.headlineMedium?.copyWith(
                    fontWeight: FontWeight.bold,
                  ),
                ),
                const SizedBox(height: 4),
                Text(
                  _sdkInitialized
                      ? 'Enter your meeting details below'
                      : _status,
                  style: theme.textTheme.bodyMedium?.copyWith(
                    color: _sdkInitFailed
                        ? theme.colorScheme.error
                        : theme.colorScheme.onSurfaceVariant,
                  ),
                  textAlign: TextAlign.center,
                ),
                if (_sdkInitFailed) ...[
                  const SizedBox(height: 16),
                  OutlinedButton.icon(
                    onPressed: _initSdk,
                    icon: const Icon(Icons.refresh_rounded),
                    label: const Text('Retry'),
                  ),
                ],
                const SizedBox(height: 32),

                // Form Card
                Card(
                  elevation: 0,
                  shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.circular(16),
                    side: BorderSide(
                      color: theme.colorScheme.outlineVariant,
                    ),
                  ),
                  child: Padding(
                    padding: const EdgeInsets.all(20),
                    child: Column(
                      children: [
                        _buildTextField(
                          controller: _meetingIdController,
                          label: 'Meeting ID',
                          icon: Icons.tag_rounded,
                          keyboardType: TextInputType.number,
                        ),
                        const SizedBox(height: 12),
                        _buildTextField(
                          controller: _meetingPasswordController,
                          label: 'Password',
                          icon: Icons.lock_outline_rounded,
                          obscureText: true,
                        ),
                        const SizedBox(height: 12),
                        _buildTextField(
                          controller: _displayNameController,
                          label: 'Display Name',
                          icon: Icons.person_outline_rounded,
                        ),
                      ],
                    ),
                  ),
                ),
                const SizedBox(height: 20),

                // Join Button
                SizedBox(
                  width: double.infinity,
                  height: 52,
                  child: FilledButton(
                    onPressed: _sdkInitialized && !_joining
                        ? _joinMeeting
                        : null,
                    style: FilledButton.styleFrom(
                      shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(14),
                      ),
                    ),
                    child: _joining
                        ? const SizedBox(
                            width: 22,
                            height: 22,
                            child: CircularProgressIndicator(
                              strokeWidth: 2.5,
                              color: Colors.white,
                            ),
                          )
                        : const Text(
                            'Join Meeting',
                            style: TextStyle(
                              fontSize: 16,
                              fontWeight: FontWeight.w600,
                            ),
                          ),
                  ),
                ),
                const SizedBox(height: 32),
              ],
            ),
          ),
        ),
      ),
    );
  }

  Widget _buildTextField({
    required TextEditingController controller,
    required String label,
    required IconData icon,
    TextInputType? keyboardType,
    bool obscureText = false,
  }) {
    return TextField(
      controller: controller,
      keyboardType: keyboardType,
      obscureText: obscureText,
      decoration: InputDecoration(
        labelText: label,
        prefixIcon: Icon(icon),
        filled: true,
        fillColor: Theme.of(context).colorScheme.surfaceContainerLowest,
        border: OutlineInputBorder(
          borderRadius: BorderRadius.circular(12),
          borderSide: BorderSide.none,
        ),
        enabledBorder: OutlineInputBorder(
          borderRadius: BorderRadius.circular(12),
          borderSide: BorderSide(
            color: Theme.of(context).colorScheme.outlineVariant,
            width: 0.5,
          ),
        ),
        focusedBorder: OutlineInputBorder(
          borderRadius: BorderRadius.circular(12),
          borderSide: BorderSide(
            color: Theme.of(context).colorScheme.primary,
            width: 1.5,
          ),
        ),
      ),
    );
  }
}
0
likes
0
points
249
downloads

Publisher

unverified uploader

Weekly Downloads

A Flutter plugin for Zoom Meeting SDK with support for joining meetings, email login, meeting controls, and real-time meeting events.

Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

flutter, plugin_platform_interface

More

Packages that depend on flutter_zoom_sdk_advanced

Packages that implement flutter_zoom_sdk_advanced