screen_share_plugin 0.0.2 copy "screen_share_plugin: ^0.0.2" to clipboard
screen_share_plugin: ^0.0.2 copied to clipboard

PlatformAndroid

A Flutter plugin for Android screen sharing using WebRTC and native Kotlin code.

screen_share_plugin #

A Flutter plugin that enables real-time screen sharing on Android using native Kotlin code and displays the stream via flutter_webrtc.

Features #

  • ✅ Real-time screen sharing on Android.
  • ✅ Screen preview powered by flutter_webrtc. (Thanks to the flutter_webrtc team).
  • ✅ Native Android code written in Kotlin.
  • ✅ Tested with Flutter 3.29 and compile SDK version up to 35 to reduce compatibility issues.

Getting Started #

1. Installation #

Add the plugin to your pubspec.yaml:

dependencies:
  screen_share_plugin: ^0.0.2

2. Android Setup #

Ensure you are using:

  • Flutter SDK: 3.29.0
  • compileSdkVersion: 35 (in your android/app/build.gradle)
  • Allow Permissions from app info: Notifications, Camera, Microphone for screen sharing

3. Permissions and Manifest Configuration (Optional) #

Add the required permissions and service declaration to your AndroidManifest.xml. If your configuration doesn't work out of the box, try adding these manually:

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
  <!-- Permissions required for screen sharing -->
  <uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION" />
  <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
  <uses-permission android:name="android.permission.RECORD_AUDIO" />
  <uses-permission android:name="android.permission.CAMERA" />
  <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

  <application
      android:label="screen_share_plugin_example"
      android:name="${applicationName}"
      android:icon="@mipmap/ic_launcher">

      <!-- Foreground service declaration for media projection -->
      <service
          android:name="com.example.screen_share_plugin.ScreenCaptureService"
          android:enabled="true"
          android:exported="false"
          android:foregroundServiceType="mediaProjection" />

      <activity
          android:name=".MainActivity"
          android:exported="true"
          android:launchMode="singleTop"
          android:theme="@style/LaunchTheme"
          android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
          android:hardwareAccelerated="true"
          android:windowSoftInputMode="adjustResize">

          <meta-data
              android:name="io.flutter.embedding.android.NormalTheme"
              android:resource="@style/NormalTheme" />

          <intent-filter>
              <action android:name="android.intent.action.MAIN" />
              <category android:name="android.intent.category.LAUNCHER" />
          </intent-filter>
      </activity>

      <meta-data
          android:name="flutterEmbedding"
          android:value="2" />
  </application>
</manifest>

Example Usage #

import 'package:flutter/material.dart';
import 'package:flutter_webrtc/flutter_webrtc.dart';
import 'package:screen_share_plugin/screen_share_plugin.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: ScreenShareDemo(),
      debugShowCheckedModeBanner: false,
    );
  }
}

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

  @override
  State<ScreenShareDemo> createState() => _ScreenShareDemoState();
}

class _ScreenShareDemoState extends State<ScreenShareDemo> {
  bool _isSharing = false;
  String _status = "Idle";
  MediaStream? _localStream;
  final RTCVideoRenderer _localRenderer = RTCVideoRenderer();

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

  Future<void> _initializeRenderer() async {
    await _localRenderer.initialize();
  }

  Future<void> _startScreenSharing() async {
    try {
      setState(() {
        _status = "Requesting permission...";
      });

      // Start the screen share plugin
      await ScreenSharePlugin.startScreenShare();

      // After starting the service, grab the display media
      final mediaConstraints = <String, dynamic>{
        'audio': false,
        'video': {
          'mandatory': {
            'minWidth': 640,
            'minHeight': 480,
            'minFrameRate': 30,
          },
          'facingMode': 'user',
          'optional': [],
        }
      };

      _localStream =
          await navigator.mediaDevices.getDisplayMedia(mediaConstraints);
      _localRenderer.srcObject = _localStream;

      setState(() {
        _isSharing = true;
        _status = "Screen sharing active";
      });
    } catch (e) {
      setState(() {
        _status = "Error: ${e.toString()}";
      });
    }
  }

  Future<void> _stopScreenSharing() async {
    try {
      await ScreenSharePlugin.stopScreenShare();

      setState(() {
        _isSharing = false;
        _status = "Screen sharing stopped";
      });

      _localStream?.dispose();
      _localRenderer.srcObject = null;
    } catch (e) {
      setState(() {
        _status = "Error: ${e.toString()}";
      });
    }
  }

  @override
  void dispose() {
    _localStream?.dispose();
    _localRenderer.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Screen Sharing Plugin Example"),
      ),
      body: Center(
        child: Padding(
          padding: const EdgeInsets.all(20.0),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Text(
                _status,
                style: const TextStyle(fontSize: 18),
              ),
              const SizedBox(height: 30),
              _isSharing
                  ? SizedBox(
                      width: 640,
                      height: 480,
                      child: RTCVideoView(_localRenderer),
                    )
                  : const Center(child: Text("No Screen Sharing")),
              const SizedBox(height: 30),
              ElevatedButton.icon(
                icon: Icon(_isSharing ? Icons.stop : Icons.screen_share),
                label:
                    Text(_isSharing ? "Stop Sharing" : "Start Screen Sharing"),
                onPressed:
                    _isSharing ? _stopScreenSharing : _startScreenSharing,
              ),
            ],
          ),
        ),
      ),
    );
  }
}

License #

MIT License


Support #

If you like this plugin, support me on Buy Me A Coffee.

If this plugin helped you, please consider subscribing to my YouTube channel 🎥 Yogx World


2
likes
160
points
106
downloads

Publisher

unverified uploader

Weekly Downloads

A Flutter plugin for Android screen sharing using WebRTC and native Kotlin code.

Repository (GitHub)
View/report issues

Documentation

API reference

License

MIT (license)

Dependencies

flutter, plugin_platform_interface

More

Packages that depend on screen_share_plugin