Skip to content

Latest commit

 

History

3 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Camera Service Plugin

pub package License: MIT

A powerful and easy-to-use Flutter plugin for camera operations on Android. This plugin provides seamless integration for image capture, video recording, and audio recording with automatic permission handling.

Features

🚀 Easy Integration - Simple API with minimal setup required
📸 Image Capture - High-quality image capture with Base64 encoding
🎥 Video Recording - Full video recording capabilities
🎙️ Audio Recording - Audio recording functionality
🔐 Automatic Permissions - Built-in permission handling for camera and microphone
CameraX Integration - Uses Android's modern CameraX library for optimal performance
🛡️ Error Handling - Comprehensive error handling and user feedback

Supported Platforms

Platform Support
Android
iOS ❌ (Coming Soon)

Requirements

  • Flutter SDK: >=3.3.0
  • Dart SDK: >=3.8.1
  • Android: API level 21 (Android 5.0) or higher

Installation

Add this to your package's pubspec.yaml file:

dependencies:
  camera_service_plugin:
    git:
      url: https://github.com/De-pitcher/camera_service_plugin.git

Or for local development:

dependencies:
  camera_service_plugin:
    path: ../path/to/camera_service_plugin

Then run:

flutter pub get

Android Setup

1. Update android/app/build.gradle

Ensure your app targets the correct SDK versions:

android {
    compileSdkVersion 34
    
    defaultConfig {
        minSdkVersion 21
        targetSdkVersion 34
    }
}

2. Add Permissions

Add the following permissions to your android/app/src/main/AndroidManifest.xml:

<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" 
    android:maxSdkVersion="32" />

3. Proguard Rules (if using obfuscation)

Add to your android/app/proguard-rules.pro:

-keep class androidx.camera.** { *; }
-keep class com.rodeni.camera_service_plugin.** { *; }

Usage

Basic Implementation

import 'package:camera_service_plugin/camera_service_plugin.dart';
import 'package:flutter/material.dart';

class CameraExample extends StatefulWidget {
  @override
  _CameraExampleState createState() => _CameraExampleState();
}

class _CameraExampleState extends State<CameraExample> {
  String? _capturedImage;
  bool _isLoading = false;

  Future<void> _captureImage() async {
    setState(() => _isLoading = true);
    
    try {
      final String? result = await CameraServicePlugin.captureImage();
      
      if (result != null) {
        setState(() => _capturedImage = result);
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(content: Text('Image captured successfully!')),
        );
      }
    } catch (e) {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('Error: $e')),
      );
    } finally {
      setState(() => _isLoading = false);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Camera Service Example')),
      body: Column(
        children: [
          ElevatedButton(
            onPressed: _isLoading ? null : _captureImage,
            child: _isLoading 
              ? CircularProgressIndicator() 
              : Text('Capture Image'),
          ),
          if (_capturedImage != null)
            Expanded(
              child: Image.memory(
                base64Decode(_capturedImage!),
                fit: BoxFit.contain,
              ),
            ),
        ],
      ),
    );
  }
}

Complete Example with All Features

import 'package:camera_service_plugin/camera_service_plugin.dart';
import 'package:flutter/material.dart';
import 'dart:convert';

class FullCameraExample extends StatefulWidget {
  @override
  _FullCameraExampleState createState() => _FullCameraExampleState();
}

class _FullCameraExampleState extends State<FullCameraExample> {
  String? _lastResult;
  bool _isProcessing = false;

  Future<void> _performCameraOperation(
    Future<String?> Function() operation,
    String operationName,
  ) async {
    setState(() => _isProcessing = true);
    
    try {
      final result = await operation();
      setState(() => _lastResult = result);
      
      if (result != null) {
        _showSuccess('$operationName completed successfully!');
      } else {
        _showError('$operationName failed');
      }
    } catch (e) {
      _showError('$operationName error: $e');
    } finally {
      setState(() => _isProcessing = false);
    }
  }

  void _showSuccess(String message) {
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(
        content: Text(message),
        backgroundColor: Colors.green,
      ),
    );
  }

  void _showError(String message) {
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(
        content: Text(message),
        backgroundColor: Colors.red,
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Camera Service Plugin'),
        backgroundColor: Colors.blue,
      ),
      body: Padding(
        padding: EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            Text(
              'Camera Operations',
              style: Theme.of(context).textTheme.headlineSmall,
              textAlign: TextAlign.center,
            ),
            SizedBox(height: 20),
            
            _buildOperationButton(
              'Capture Image',
              Icons.camera_alt,
              () => _performCameraOperation(
                CameraServicePlugin.captureImage,
                'Image capture',
              ),
            ),
            
            _buildOperationButton(
              'Record Video',
              Icons.videocam,
              () => _performCameraOperation(
                () => CameraServicePlugin.recordVideo(
                  maxDuration: Duration(seconds: 15),
                ),
                'Video recording',
              ),
            ),
            
            _buildOperationButton(
              'Record Audio',
              Icons.mic,
              () => _performCameraOperation(
                () => CameraServicePlugin.recordAudio(
                  maxDuration: Duration(seconds: 30),
                ),
                'Audio recording',
              ),
            ),
            
            if (_lastResult != null) ...[
              SizedBox(height: 20),
              Text(
                'Last Result:',
                style: Theme.of(context).textTheme.titleMedium,
              ),
              SizedBox(height: 8),
              Container(
                padding: EdgeInsets.all(12),
                decoration: BoxDecoration(
                  color: Colors.grey[100],
                  borderRadius: BorderRadius.circular(8),
                ),
                child: Text(
                  'Data captured (${_lastResult!.length} characters)',
                  style: TextStyle(fontFamily: 'monospace'),
                ),
              ),
            ],
          ],
        ),
      ),
    );
  }

  Widget _buildOperationButton(
    String label,
    IconData icon,
    VoidCallback onPressed,
  ) {
    return Padding(
      padding: EdgeInsets.symmetric(vertical: 8.0),
      child: ElevatedButton.icon(
        onPressed: _isProcessing ? null : onPressed,
        icon: _isProcessing 
          ? SizedBox(
              width: 16,
              height: 16,
              child: CircularProgressIndicator(strokeWidth: 2),
            )
          : Icon(icon),
        label: Text(label),
        style: ElevatedButton.styleFrom(
          padding: EdgeInsets.all(16),
          textStyle: TextStyle(fontSize: 16),
        ),
      ),
    );
  }
}

API Reference

CameraServicePlugin

The main class providing camera functionality.

Methods

captureImage()

Captures a single image using the device camera.

static Future<String?> captureImage()

Returns: Future<String?> - Base64 encoded image data or null if capture fails.

Throws: PlatformException if camera access is denied or operation fails.

recordVideo()

Records a video using the device camera.

static Future<String?> recordVideo({Duration? maxDuration})

Parameters:

  • maxDuration (optional): Maximum recording duration. If not provided, defaults to 10 seconds.

Returns: Future<String?> - Base64 encoded video data or null if recording fails.

Throws: PlatformException if camera access is denied or operation fails.

Example:

// Record a 15-second video
final video = await CameraServicePlugin.recordVideo(
  maxDuration: Duration(seconds: 15),
);
recordAudio()

Records audio using the device microphone.

static Future<String?> recordAudio({Duration? maxDuration})

Parameters:

  • maxDuration (optional): Maximum recording duration. If not provided, defaults to 30 seconds.

Returns: Future<String?> - Base64 encoded audio data or null if recording fails.

Throws: PlatformException if microphone access is denied or operation fails.

Example:

// Record a 30-second audio clip
final audio = await CameraServicePlugin.recordAudio(
  maxDuration: Duration(seconds: 30),
);

Permission Handling

The plugin automatically handles permission requests for:

  • CAMERA - Required for image capture and video recording
  • RECORD_AUDIO - Required for audio recording and video with audio

No additional permission handling code is required in your Flutter app. The plugin will:

  1. Check if permissions are granted
  2. Request permissions if needed
  3. Show appropriate error messages if permissions are denied

Error Handling

The plugin provides comprehensive error handling:

try {
  final result = await CameraServicePlugin.captureImage();
  // Handle success
} on PlatformException catch (e) {
  switch (e.code) {
    case 'PERMISSION_DENIED':
      // Handle permission denial
      break;
    case 'CAMERA_ERROR':
      // Handle camera-specific errors
      break;
    default:
      // Handle other errors
      break;
  }
}

Technical Details

Android Implementation

  • CameraX Library: Uses Android's modern CameraX library for camera operations
  • Automatic Lifecycle Management: Handles camera lifecycle automatically
  • Performance Optimized: Efficient resource management and background processing
  • Base64 Encoding: All media data is returned as Base64 for easy handling

Architecture

Flutter App
    ↓
Method Channel
    ↓
CameraServicePlugin (Kotlin)
    ↓
CameraService (Java)
    ↓
CameraX Library

Troubleshooting

Common Issues

Q: Camera not working on Android
A: Ensure minimum SDK version is 21 and all required permissions are added to AndroidManifest.xml.

Q: App crashes when calling camera methods
A: Check that your app has the necessary permissions and the device has a camera.

Q: Base64 data seems corrupted
A: Ensure you're properly decoding the Base64 string and handling it as binary data.

Q: Build errors with Gradle
A: Make sure your compileSdkVersion is 34 or higher and you have the latest Android build tools.

Getting Help

If you encounter issues:

  1. Check the example app for reference implementation
  2. Ensure all setup steps are completed correctly
  3. Verify that your device/emulator has camera capabilities
  4. Check the Flutter console for detailed error messages

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Changelog

See CHANGELOG.md for version history and updates.

About

A high-performance Flutter plugin for Android powered by CameraX. Features seamless image capture, video & audio recording with Base64 encoding and auto-permission handling.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages