teleconsultation_core 0.2.0 copy "teleconsultation_core: ^0.2.0" to clipboard
teleconsultation_core: ^0.2.0 copied to clipboard

PlatformAndroidiOS
unlisted

Shared teleconsultation runtime for Manastik Flutter apps.

Teleconsultation Core #

A robust Flutter plugin for managing and orchestrating teleconsultation meetings. It wraps the core meeting logic (using realtimekit_ui) and provides deep native integration for Android and iOS, including background processing, Picture-in-Picture (PiP) mode, and ongoing meeting notifications.

Features #

  • Native Meeting Process: On Android, the meeting can run in a separate Flutter isolate (engine) to ensure stability and independent resource management.
  • Picture-in-Picture (PiP): Built-in support for native PiP mode, allowing users to navigate the app or the device while continuing their consultation.
  • Ongoing Meeting Tracker: A built-in ChangeNotifier to track the state of a meeting (ongoing/ended) and its duration globally across the app.
  • Persistent Notifications: Native ongoing notifications (Android) indicating an active consultation.
  • Device Management: API to query and switch between audio and camera devices.
  • Screen Sharing: Meeting-scoped sharer controls and consumer rendering APIs without exposing SDK internals.

Getting Started #

Configuration #

Before launching any meetings, configure the core package (typically in your main.dart):

import 'package:teleconsultation_core/teleconsultation_core.dart';

void main() {
  TeleconsultationCore.configure(
    const TeleconsultationCoreConfig(
      androidNotificationChannelId: 'ongoing_consultation',
      androidNotificationChannelName: 'Ongoing consultation',
      androidNotificationSmallIcon: 'ic_notification',
    ),
  );
  
  runApp(const MyApp());
}

Android Setup #

Because the package uses a background isolate on Android to run the meeting independently, you must define a top-level @pragma('vm:entry-point') function to serve as the entry point for the meeting process:

@pragma('vm:entry-point')
void meetingMain() {
  runTeleconsultationMeetingProcess(
    config: TeleconsultationMeetingProcessConfig(
      meetingAppBuilder: (context, meetingContext) {
        return CustomMeetingApp(
          meetingId: meetingContext.credentials.meetingId,
          doctorName: meetingContext.credentials.displayName,
          // ...
        );
      },
    ),
  );
}

Implementation & Usage #

Launching a Meeting #

To start a teleconsultation, use the TeleconsultationLauncher. This will handle the platform-specific routing (launching the MeetingActivity on Android or pushing the route natively).

await TeleconsultationLauncher.launch(
  credentials: TeleconsultationCredentials(
    authToken: 'your-auth-token',
    displayName: 'Dr. Smith',
    meetingId: 'meeting-123',
  ),
  options: const TeleconsultationLaunchOptions(
    audioEnabled: true,
    videoEnabled: true,
    skipSetupScreen: true,
  ),
  details: const TeleconsultationMeetingDetails(
    meetingId: 'meeting-123',
    patientName: 'John Doe',
  ),
);

Tracking Meeting State #

You can track if a meeting is actively running and its duration from anywhere in your main app isolate. This is incredibly useful for showing global banners, preventing user logout during a meeting, or handling custom in-app PiP logic.

import 'package:teleconsultation_core/teleconsultation_core.dart';

// Inside a Widget:
ListenableBuilder(
  listenable: TeleconsultationMeetingTracker.instance,
  builder: (context, _) {
    final tracker = TeleconsultationMeetingTracker.instance;
    
    if (tracker.isOngoing) {
      return Container(
        color: Colors.green,
        child: Text(
          'Meeting in progress: ${tracker.duration.inMinutes}:${(tracker.duration.inSeconds % 60).toString().padLeft(2, '0')}',
        ),
      );
    }
    
    return const SizedBox.shrink();
  },
)

The tracker automatically starts when TeleconsultationLauncher.launch() is called, and automatically stops when the native layer broadcasts a meetingClosed event.

Picture-in-Picture (PiP) #

You can manage PiP state programmatically using the launcher:

// Check if PiP is supported on the device
bool isSupported = await TeleconsultationLauncher.isPipSupported();

// Enter PiP mode manually
if (isSupported) {
  await TeleconsultationLauncher.enterPip();
}

// Update native PiP actions (e.g., mute/unmute buttons on the PiP window)
await TeleconsultationLauncher.updatePipActions(
  audioEnabled: false,
  videoEnabled: true,
);

You can also listen to PiP state changes:

TeleconsultationLauncher.setPipStateHandler((bool isPipActive) {
  if (isPipActive) {
    // Hide certain UI elements
  }
});

Ending the Process Manually #

To forcefully terminate the meeting process from the main app isolate:

await TeleconsultationLauncher.finishMeetingProcess();

Screen Sharing #

Every TeleconsultationMeetingPage builder receives a meeting-scoped controller. Pass it to your room UI instead of reaching into RealtimeKit globals:

TeleconsultationMeetingPage(
  credentials: credentials,
  builder: (context, meetingContext) {
    return MyMeetingRoom(screenShare: meetingContext.screenShare);
  },
);

Sharers can use the controller as a Listenable and guard the action with canStart:

ListenableBuilder(
  listenable: screenShare,
  builder: (context, _) {
    return IconButton(
      onPressed: !screenShare.isRequestPending &&
              (screenShare.isSharing || screenShare.canStart)
          ? screenShare.toggle
          : null,
      icon: Icon(
        screenShare.isSharing
            ? Icons.stop_screen_share_outlined
            : Icons.screen_share_outlined,
      ),
    );
  },
);

start(), stop(), and toggle() return whether the request was accepted locally. RealtimeKit completes capture asynchronously, so observe isSharing and lastError for the result.

Consumers can render any active local or remote share:

ListenableBuilder(
  listenable: screenShare,
  builder: (context, _) {
    final shares = screenShare.shares;
    if (shares.isEmpty) {
      return const Center(child: Text('No one is sharing'));
    }
    return TeleconsultationScreenShareView(share: shares.first);
  },
);

The plugin contributes FOREGROUND_SERVICE_MEDIA_PROJECTION to the merged Android manifest, as required for Android 14+. On iOS, the package invokes RealtimeKit's capture API, but a host app that needs system-wide sharing must complete RealtimeKit's ReplayKit target and entitlement setup. See the RealtimeKit Flutter screen-share documentation.

0
likes
100
points
105
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Shared teleconsultation runtime for Manastik Flutter apps.

License

(pending) (license)

Dependencies

flutter, flutter_riverpod, permission_handler, realtimekit_ui

More

Packages that depend on teleconsultation_core

Packages that implement teleconsultation_core