i_google_drive 1.0.0 copy "i_google_drive: ^1.0.0" to clipboard
i_google_drive: ^1.0.0 copied to clipboard

A comprehensive Flutter package for uploading, downloading, and managing files in Google Drive with easy-to-use API and full authentication support.

example/lib/main.dart

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:file_picker/file_picker.dart';
import 'package:i_google_drive/i_google_drive.dart';
import 'package:google_sign_in/google_sign_in.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'i_google_drive Example',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const GoogleDriveExamplePage(),
    );
  }
}

/// Example Flutter page demonstrating Google Drive file operations
class GoogleDriveExamplePage extends StatefulWidget {
  const GoogleDriveExamplePage({super.key});

  @override
  State<GoogleDriveExamplePage> createState() => _GoogleDriveExamplePageState();
}

class _GoogleDriveExamplePageState extends State<GoogleDriveExamplePage> {
  final GoogleDriveService _driveService = GoogleDriveService();
  bool _isLoading = false;
  bool _isSignedIn = false;
  GoogleSignInAccount? _currentUser;
  List<DriveFile> _files = [];
  String? _errorMessage;
  String? _successMessage;

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

  Future<void> _checkAuthStatus() async {
    setState(() {
      _isLoading = true;
      _errorMessage = null;
    });

    try {
      final isSignedIn = await _driveService.isSignedIn();
      final user = await _driveService.getCurrentUser();

      setState(() {
        _isSignedIn = isSignedIn;
        _currentUser = user;
        _isLoading = false;
      });

      if (isSignedIn) {
        await _loadFiles();
      }
    } catch (e) {
      setState(() {
        _errorMessage = 'Error checking auth status: $e';
        _isLoading = false;
      });
    }
  }

  Future<void> _signIn() async {
    setState(() {
      _isLoading = true;
      _errorMessage = null;
      _successMessage = null;
    });

    try {
      final account = await _driveService.signIn();
      setState(() {
        _isSignedIn = true;
        _currentUser = account;
        _isLoading = false;
        _successMessage = 'Signed in successfully as ${account.email}';
      });
      await _loadFiles();
    } on AuthenticationException catch (e) {
      setState(() {
        _errorMessage = 'Authentication error: ${e.message}';
        _isLoading = false;
      });
    } catch (e) {
      setState(() {
        _errorMessage = 'Sign in failed: $e';
        _isLoading = false;
      });
    }
  }

  Future<void> _signOut() async {
    setState(() {
      _isLoading = true;
      _errorMessage = null;
      _successMessage = null;
    });

    try {
      await _driveService.signOut();
      setState(() {
        _isSignedIn = false;
        _currentUser = null;
        _files = [];
        _isLoading = false;
        _successMessage = 'Signed out successfully';
      });
    } catch (e) {
      setState(() {
        _errorMessage = 'Sign out failed: $e';
        _isLoading = false;
      });
    }
  }

  Future<void> _loadFiles() async {
    setState(() {
      _isLoading = true;
      _errorMessage = null;
    });

    try {
      final files = await _driveService.listFiles(pageSize: 50);
      setState(() {
        _files = files;
        _isLoading = false;
      });
    } catch (e) {
      setState(() {
        _errorMessage = 'Failed to load files: $e';
        _isLoading = false;
      });
    }
  }

  Future<void> _uploadFile() async {
    setState(() {
      _isLoading = true;
      _errorMessage = null;
      _successMessage = null;
    });

    try {
      // Pick a file
      final result = await FilePicker.platform.pickFiles(
        type: FileType.any,
      );

      if (result == null || result.files.single.path == null) {
        setState(() {
          _isLoading = false;
        });
        return;
      }

      final filePath = result.files.single.path!;
      final fileName = result.files.single.name;
      final file = File(filePath);

      if (!await file.exists()) {
        setState(() {
          _errorMessage = 'Selected file does not exist';
          _isLoading = false;
        });
        return;
      }

      final uploadResult = await _driveService.uploadFile(
        file,
        fileName: fileName,
      );

      if (uploadResult.success) {
        setState(() {
          _successMessage =
              'File uploaded successfully: ${uploadResult.file!.name}';
          _isLoading = false;
        });
        await _loadFiles();
      } else {
        setState(() {
          _errorMessage = 'Upload failed: ${uploadResult.error}';
          _isLoading = false;
        });
      }
    } on UploadException catch (e) {
      setState(() {
        _errorMessage = 'Upload error: ${e.message}';
        _isLoading = false;
      });
    } catch (e) {
      setState(() {
        _errorMessage = 'Upload failed: $e';
        _isLoading = false;
      });
    }
  }

  Future<void> _downloadFile(DriveFile file) async {
    setState(() {
      _isLoading = true;
      _errorMessage = null;
      _successMessage = null;
    });

    try {
      final downloadedFile = await _driveService.downloadFile(
        file.id,
        fileName: 'downloaded_${file.name}',
      );

      setState(() {
        _successMessage = 'File downloaded to: ${downloadedFile.path}';
        _isLoading = false;
      });

      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(
            content: Text('File downloaded to: ${downloadedFile.path}'),
            duration: const Duration(seconds: 3),
          ),
        );
      }
    } on DownloadException catch (e) {
      setState(() {
        _errorMessage = 'Download error: ${e.message}';
        _isLoading = false;
      });
    } on FileNotFoundException catch (e) {
      setState(() {
        _errorMessage = 'File not found: ${e.message}';
        _isLoading = false;
      });
    } catch (e) {
      setState(() {
        _errorMessage = 'Download failed: $e';
        _isLoading = false;
      });
    }
  }

  Future<void> _deleteFile(DriveFile file) async {
    final confirmed = await showDialog<bool>(
      context: context,
      builder: (context) => AlertDialog(
        title: const Text('Delete File'),
        content: Text('Are you sure you want to delete "${file.name}"?'),
        actions: [
          TextButton(
            onPressed: () => Navigator.of(context).pop(false),
            child: const Text('Cancel'),
          ),
          TextButton(
            onPressed: () => Navigator.of(context).pop(true),
            style: TextButton.styleFrom(foregroundColor: Colors.red),
            child: const Text('Delete'),
          ),
        ],
      ),
    );

    if (confirmed != true) return;

    setState(() {
      _isLoading = true;
      _errorMessage = null;
      _successMessage = null;
    });

    try {
      await _driveService.deleteFile(file.id);
      setState(() {
        _successMessage = 'File deleted successfully';
        _isLoading = false;
      });
      await _loadFiles();
    } catch (e) {
      setState(() {
        _errorMessage = 'Delete failed: $e';
        _isLoading = false;
      });
    }
  }

  String _formatFileSize(int? bytes) {
    if (bytes == null) return 'Unknown size';
    if (bytes < 1024) return '$bytes B';
    if (bytes < 1024 * 1024) return '${(bytes / 1024).toStringAsFixed(1)} KB';
    return '${(bytes / (1024 * 1024)).toStringAsFixed(1)} MB';
  }

  IconData _getFileIcon(String? mimeType) {
    if (mimeType == null) return Icons.insert_drive_file;
    if (mimeType.contains('image')) return Icons.image;
    if (mimeType.contains('video')) return Icons.video_file;
    if (mimeType.contains('audio')) return Icons.audiotrack;
    if (mimeType.contains('pdf')) return Icons.picture_as_pdf;
    if (mimeType.contains('folder') || mimeType.contains('directory')) {
      return Icons.folder;
    }
    return Icons.insert_drive_file;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('i_google_drive Example'),
        actions: [
          if (_isSignedIn)
            IconButton(
              icon: const Icon(Icons.refresh),
              onPressed: _isLoading ? null : _loadFiles,
              tooltip: 'Refresh files',
            ),
        ],
      ),
      body: _isLoading && _files.isEmpty
          ? const Center(child: CircularProgressIndicator())
          : Column(
              children: [
                // Auth Section
                Container(
                  padding: const EdgeInsets.all(16),
                  color: Theme.of(context).colorScheme.surfaceVariant,
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.stretch,
                    children: [
                      if (_currentUser != null)
                        Row(
                          children: [
                            CircleAvatar(
                              backgroundImage: _currentUser!.photoUrl != null
                                  ? NetworkImage(_currentUser!.photoUrl!)
                                  : null,
                              child: _currentUser!.photoUrl == null
                                  ? const Icon(Icons.person)
                                  : null,
                            ),
                            const SizedBox(width: 12),
                            Expanded(
                              child: Column(
                                crossAxisAlignment: CrossAxisAlignment.start,
                                children: [
                                  Text(
                                    _currentUser!.displayName ?? 'User',
                                    style: Theme.of(context).textTheme.titleMedium,
                                  ),
                                  Text(
                                    _currentUser!.email,
                                    style: Theme.of(context).textTheme.bodySmall,
                                  ),
                                ],
                              ),
                            ),
                          ],
                        ),
                      const SizedBox(height: 12),
                      ElevatedButton.icon(
                        onPressed: _isLoading
                            ? null
                            : (_isSignedIn ? _signOut : _signIn),
                        icon: Icon(_isSignedIn ? Icons.logout : Icons.login),
                        label: Text(_isSignedIn ? 'Sign Out' : 'Sign In'),
                      ),
                    ],
                  ),
                ),

                // Messages
                if (_errorMessage != null)
                  Container(
                    width: double.infinity,
                    padding: const EdgeInsets.all(12),
                    color: Colors.red.shade100,
                    child: Row(
                      children: [
                        const Icon(Icons.error, color: Colors.red),
                        const SizedBox(width: 8),
                        Expanded(
                          child: Text(
                            _errorMessage!,
                            style: const TextStyle(color: Colors.red),
                          ),
                        ),
                        IconButton(
                          icon: const Icon(Icons.close, size: 20),
                          onPressed: () {
                            setState(() => _errorMessage = null);
                          },
                        ),
                      ],
                    ),
                  ),
                if (_successMessage != null)
                  Container(
                    width: double.infinity,
                    padding: const EdgeInsets.all(12),
                    color: Colors.green.shade100,
                    child: Row(
                      children: [
                        const Icon(Icons.check_circle, color: Colors.green),
                        const SizedBox(width: 8),
                        Expanded(
                          child: Text(
                            _successMessage!,
                            style: const TextStyle(color: Colors.green),
                          ),
                        ),
                        IconButton(
                          icon: const Icon(Icons.close, size: 20),
                          onPressed: () {
                            setState(() => _successMessage = null);
                          },
                        ),
                      ],
                    ),
                  ),

                // Action Buttons
                if (_isSignedIn)
                  Padding(
                    padding: const EdgeInsets.all(16),
                    child: Row(
                      children: [
                        Expanded(
                          child: ElevatedButton.icon(
                            onPressed: _isLoading ? null : _uploadFile,
                            icon: const Icon(Icons.upload_file),
                            label: const Text('Upload File'),
                          ),
                        ),
                        const SizedBox(width: 12),
                        Expanded(
                          child: ElevatedButton.icon(
                            onPressed: _isLoading ? null : _loadFiles,
                            icon: const Icon(Icons.refresh),
                            label: const Text('Refresh'),
                          ),
                        ),
                      ],
                    ),
                  ),

                // Files List
                if (_isSignedIn)
                  Expanded(
                    child: _files.isEmpty
                        ? Center(
                            child: Column(
                              mainAxisAlignment: MainAxisAlignment.center,
                              children: [
                                Icon(
                                  Icons.folder_open,
                                  size: 64,
                                  color: Colors.grey.shade400,
                                ),
                                const SizedBox(height: 16),
                                Text(
                                  'No files found',
                                  style: TextStyle(
                                    color: Colors.grey.shade600,
                                    fontSize: 16,
                                  ),
                                ),
                                const SizedBox(height: 8),
                                TextButton(
                                  onPressed: _loadFiles,
                                  child: const Text('Refresh'),
                                ),
                              ],
                            ),
                          )
                        : ListView.builder(
                            itemCount: _files.length,
                            itemBuilder: (context, index) {
                              final file = _files[index];
                              final isFolder = file.mimeType ==
                                  'application/vnd.google-apps.folder';

                              return ListTile(
                                leading: Icon(
                                  _getFileIcon(file.mimeType),
                                  color: isFolder
                                      ? Colors.blue
                                      : Theme.of(context).iconTheme.color,
                                ),
                                title: Text(file.name),
                                subtitle: Column(
                                  crossAxisAlignment: CrossAxisAlignment.start,
                                  children: [
                                    if (file.size != null)
                                      Text(
                                        _formatFileSize(file.size),
                                        style: Theme.of(context)
                                            .textTheme
                                            .bodySmall,
                                      ),
                                    if (file.modifiedTime != null)
                                      Text(
                                        'Modified: ${file.modifiedTime!.toString().split('.')[0]}',
                                        style: Theme.of(context)
                                            .textTheme
                                            .bodySmall,
                                      ),
                                  ],
                                ),
                                trailing: PopupMenuButton<String>(
                                  onSelected: (value) {
                                    if (value == 'download' && !isFolder) {
                                      _downloadFile(file);
                                    } else if (value == 'delete') {
                                      _deleteFile(file);
                                    }
                                  },
                                  itemBuilder: (context) => [
                                    if (!isFolder)
                                      const PopupMenuItem(
                                        value: 'download',
                                        child: Row(
                                          children: [
                                            Icon(Icons.download, size: 20),
                                            SizedBox(width: 8),
                                            Text('Download'),
                                          ],
                                        ),
                                      ),
                                    const PopupMenuItem(
                                      value: 'delete',
                                      child: Row(
                                        children: [
                                          Icon(
                                            Icons.delete,
                                            size: 20,
                                            color: Colors.red,
                                          ),
                                          SizedBox(width: 8),
                                          Text(
                                            'Delete',
                                            style: TextStyle(color: Colors.red),
                                          ),
                                        ],
                                      ),
                                    ),
                                  ],
                                ),
                              );
                            },
                          ),
                  ),

                if (!_isSignedIn)
                  Expanded(
                    child: Center(
                      child: Column(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: [
                          Icon(
                            Icons.cloud_upload,
                            size: 64,
                            color: Colors.grey.shade400,
                          ),
                          const SizedBox(height: 16),
                          Text(
                            'Sign in to Google Drive to get started',
                            style: TextStyle(
                              color: Colors.grey.shade600,
                              fontSize: 16,
                            ),
                          ),
                        ],
                      ),
                    ),
                  ),
              ],
            ),
    );
  }
}
3
likes
150
points
14
downloads

Publisher

verified publishermsayedq.dev

Weekly Downloads

A comprehensive Flutter package for uploading, downloading, and managing files in Google Drive with easy-to-use API and full authentication support.

Repository (GitHub)
View/report issues

Documentation

Documentation
API reference

License

MIT (license)

Dependencies

flutter, google_sign_in, http, mime, path_provider

More

Packages that depend on i_google_drive