meta_wearables_dat_flutter 0.7.1 copy "meta_wearables_dat_flutter: ^0.7.1" to clipboard
meta_wearables_dat_flutter: ^0.7.1 copied to clipboard

Unofficial Flutter plugin bridging Meta's Wearables Device Access Toolkit (DAT) for Ray-Ban Meta, Oakley Meta, and Ray-Ban Display glasses.

example/lib/main.dart

// Minimal example for the meta_wearables_dat_flutter plugin. Walks the
// happy-path: request Android permissions, register glasses, request
// camera permission, start a video stream into a Flutter Texture, stop.
//
// For the polished demo (mock devices, photo capture, full UX) see
// `samples/camera_access/` in the repo.

import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:meta_wearables_dat_flutter/meta_wearables_dat_flutter.dart';

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

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

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  RegistrationState _registrationState = RegistrationState.unavailable;
  DeviceInfo? _activeDevice;
  StreamSessionState _sessionState = StreamSessionState.stopped;
  VideoStreamSize? _videoSize;
  int? _textureId;
  String? _lastError;

  StreamSubscription<RegistrationState>? _registrationSub;
  StreamSubscription<DeviceInfo?>? _activeDeviceSub;
  StreamSubscription<StreamSessionState>? _sessionStateSub;
  StreamSubscription<VideoStreamSize>? _videoSizeSub;

  // Attached to MaterialApp.scaffoldMessengerKey so async handlers can
  // show snack bars without needing a BuildContext that lives inside the
  // MaterialApp subtree.
  final GlobalKey<ScaffoldMessengerState> _messengerKey =
      GlobalKey<ScaffoldMessengerState>();

  @override
  void initState() {
    super.initState();
    _registrationSub = MetaWearablesDat.registrationStateStream().listen(
      (s) => setState(() => _registrationState = s),
    );
    _activeDeviceSub = MetaWearablesDat.activeDeviceStream().listen(
      (d) => setState(() => _activeDevice = d),
    );
    _sessionStateSub = MetaWearablesDat.streamSessionStateStream().listen(
      (s) => setState(() => _sessionState = s),
    );
    _videoSizeSub = MetaWearablesDat.videoStreamSizeStream().listen(
      (s) => setState(() => _videoSize = s),
    );
  }

  @override
  void dispose() {
    _registrationSub?.cancel();
    _activeDeviceSub?.cancel();
    _sessionStateSub?.cancel();
    _videoSizeSub?.cancel();
    super.dispose();
  }

  Future<void> _safeCall(
    Future<void> Function() body, {
    required String label,
  }) async {
    try {
      await body();
    } on DatError catch (e) {
      _showError('$label: ${e.code} ${e.message}');
    } on PlatformException catch (e) {
      _showError('$label: ${e.code} ${e.message ?? ''}');
    } catch (e) {
      _showError('$label: $e');
    }
  }

  void _showError(String msg) {
    if (!mounted) return;
    setState(() => _lastError = msg);
    _messengerKey.currentState?.showSnackBar(SnackBar(content: Text(msg)));
  }

  Future<void> _requestAndroidPermissions() => _safeCall(
        () async {
          final granted = await MetaWearablesDat.requestAndroidPermissions();
          _messengerKey.currentState?.showSnackBar(
            SnackBar(content: Text('Android permissions: $granted')),
          );
        },
        label: 'requestAndroidPermissions',
      );

  Future<void> _connectGlasses() =>
      _safeCall(MetaWearablesDat.startRegistration, label: 'startRegistration');

  Future<void> _disconnectGlasses() => _safeCall(
        MetaWearablesDat.startUnregistration,
        label: 'startUnregistration',
      );

  Future<void> _requestCameraPermission() => _safeCall(
        () async {
          final granted = await MetaWearablesDat.requestCameraPermission();
          _messengerKey.currentState?.showSnackBar(
            SnackBar(content: Text('Camera permission: $granted')),
          );
        },
        label: 'requestCameraPermission',
      );

  Future<void> _startStreaming() => _safeCall(
        () async {
          final id = await MetaWearablesDat.startStreamSession();
          setState(() => _textureId = id);
        },
        label: 'startStreamSession',
      );

  Future<void> _stopStreaming() => _safeCall(
        () async {
          await MetaWearablesDat.stopStreamSession();
          setState(() => _textureId = null);
        },
        label: 'stopStreamSession',
      );

  @override
  Widget build(BuildContext context) {
    final registered = _registrationState == RegistrationState.registered;
    final registering = _registrationState == RegistrationState.registering;

    return MaterialApp(
      scaffoldMessengerKey: _messengerKey,
      home: Scaffold(
        appBar: AppBar(title: const Text('meta_wearables_dat_flutter example')),
        body: SafeArea(
          child: SingleChildScrollView(
            padding: const EdgeInsets.all(24),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.stretch,
              children: [
                Text('Registration: ${_registrationState.name}'),
                Text('Active device: ${_activeDevice?.name ?? 'none'}'),
                Text('Session: ${_sessionState.name}'
                    '${_videoSize != null ? '  ${_videoSize!.width}x${_videoSize!.height}' : ''}'),
                const Divider(height: 32),
                FilledButton(
                  onPressed: _requestAndroidPermissions,
                  child: const Text('Request Android permissions'),
                ),
                const SizedBox(height: 16),
                Row(
                  children: [
                    Expanded(
                      child: FilledButton(
                        onPressed:
                            registering || registered ? null : _connectGlasses,
                        child: const Text('Connect glasses'),
                      ),
                    ),
                    const SizedBox(width: 12),
                    Expanded(
                      child: OutlinedButton(
                        onPressed: registered ? _disconnectGlasses : null,
                        child: const Text('Disconnect'),
                      ),
                    ),
                  ],
                ),
                const SizedBox(height: 12),
                FilledButton.tonal(
                  onPressed: registered ? _requestCameraPermission : null,
                  child: const Text('Request camera permission'),
                ),
                const SizedBox(height: 16),
                Row(
                  children: [
                    Expanded(
                      child: FilledButton(
                        onPressed: _textureId == null && registered
                            ? _startStreaming
                            : null,
                        child: const Text('Start streaming'),
                      ),
                    ),
                    const SizedBox(width: 12),
                    Expanded(
                      child: OutlinedButton(
                        onPressed: _textureId == null ? null : _stopStreaming,
                        child: const Text('Stop'),
                      ),
                    ),
                  ],
                ),
                if (_textureId != null) ...[
                  const SizedBox(height: 16),
                  AspectRatio(
                    aspectRatio: _videoSize?.aspectRatio ?? 9 / 16,
                    child: Container(
                      color: Colors.black,
                      child: Texture(textureId: _textureId!),
                    ),
                  ),
                ],
                if (_lastError != null) ...[
                  const SizedBox(height: 16),
                  Text(
                    _lastError!,
                    style: const TextStyle(color: Colors.red),
                  ),
                ],
              ],
            ),
          ),
        ),
      ),
    );
  }
}
1
likes
160
points
102
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Unofficial Flutter plugin bridging Meta's Wearables Device Access Toolkit (DAT) for Ray-Ban Meta, Oakley Meta, and Ray-Ban Display glasses.

Repository (GitHub)
View/report issues

Topics

#meta #wearables #glasses #dat #flutter-plugin

License

MIT (license)

Dependencies

flutter, plugin_platform_interface

More

Packages that depend on meta_wearables_dat_flutter

Packages that implement meta_wearables_dat_flutter