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

A Flutter plugin for saving, retrieving, and managing files in device storage including root directory and DCIM folder. Supports images, videos, audio, and all file types with easy-to-use API.

device_storage #

A powerful Flutter plugin for managing device storage operations. Save, retrieve, delete, and list files in device storage including root directory and DCIM folder. Supports all file types including images, videos, audio, and documents.

Features #

  • ✅ Save files to root directory or DCIM folder
  • ✅ Retrieve files by filename
  • ✅ Delete files by filename
  • ✅ List all files in a directory
  • ✅ Check if file exists
  • ✅ Support for images, videos, audio, and all file types
  • ✅ Android 11+ support with proper permissions
  • ✅ iOS support
  • ✅ Easy-to-use API

Platform Support #

Platform Support
Android ✅ Yes
iOS ✅ Yes
Web ❌ No
Windows ❌ No
macOS ❌ No
Linux ❌ No

Installation #

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

dependencies:
  device_storage: ^1.0.0

Then run:

flutter pub get

Android Setup #

1. Update AndroidManifest.xml #

Add these permissions to android/app/src/main/AndroidManifest.xml:

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
    <uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
    <uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
        android:maxSdkVersion="32" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
        android:maxSdkVersion="29" />
    <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
        tools:ignore="ScopedStorage" />

    <application android:requestLegacyExternalStorage="true"
    ...>

2. Update build.gradle #

Ensure minimum SDK version in android/app/build.gradle:

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

iOS Setup #

Add these permissions to ios/Runner/Info.plist:

<key>NSPhotoLibraryAddUsageDescription</key>
<string>We need access to save media to your photo library</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>We need access to your photo library</string>

Usage #

Import #

import 'package:device_storage/device_storage.dart';

Initialize #


final storage = DeviceStorage();

Request Permissions #

// Request all necessary permissions
bool granted = await storage.requestPermissions();

// Check if permissions are granted
bool hasPermission = await storage.hasPermissions();

// Check if root access is available (Android 11+)
bool hasRoot = await storage.hasRootAccess();

Save Files #

Save to Root Directory

// Save image to root
Uint8List imageBytes = // your image bytes
String ? path = await storage.saveToRoot(
  bytes: imageBytes,
  fileName: 'my_image.jpg',
  folderPath: 'MyApp/Images', // Optional subfolder
);

// Using convenience method
await storage.saveImage(
  imageBytes: imageBytes,
  fileName: 'photo.jpg',
  folderPath: 'MyFolder',
  saveToRoot: true,
);

Save to DCIM Folder

// Save to DCIM/MyFolder
String? path = await storage.saveToDCIM(
    bytes: imageBytes,
    fileName: 'photo.jpg',
    subfolder: 'MyFolder', // Creates DCIM/MyFolder/photo.jpg
);

// Using convenience method
await storage.saveImage(
    imageBytes: imageBytes,
    fileName: 'photo.jpg',
    folderPath: 'MyFolder',
    saveToRoot: false, // Saves to DCIM
);

Save Different File Types

// Save video
await storage.saveVideo(
  videoBytes: videoBytes,
  fileName: 'video.mp4',
  folderPath: 'Videos',
  saveToRoot: true,
);

// Save audio
await storage.saveAudio(
  audioBytes: audioBytes,
  fileName: 'audio.mp3',
  folderPath: 'Music',
  saveToRoot: true,
);

// Save any file
await storage.saveFile(
  bytes: fileBytes,
  fileName: 'document.pdf',
  folderPath: 'Documents',
  saveToRoot: true,
);

Retrieve Files #

// Get file from root
Uint8List? bytes = await storage.getFromRoot(
  fileName: 'my_image.jpg',
  folderPath: 'MyApp/Images',
);

// Get file from DCIM
Uint8List? bytes = await storage.getFromDCIM(
  fileName: 'photo.jpg',
  subfolder: 'MyFolder',
);

// Using convenience method
Uint8List? bytes = await storage.getFile(
  fileName: 'photo.jpg',
  folderPath: 'MyFolder',
  fromRoot: true,
);

if (bytes != null) {
print('File size: ${bytes.length} bytes');
// Use the bytes (display image, play video, etc.)
}

Delete Files #

// Delete from root
bool deleted = await storage.deleteFromRoot(
  fileName: 'my_image.jpg',
  folderPath: 'MyApp/Images',
);

// Delete from DCIM
bool deleted = await storage.deleteFromDCIM(
  fileName: 'photo.jpg',
  subfolder: 'MyFolder',
);

// Using convenience method
bool deleted = await storage.deleteFile(
  fileName: 'photo.jpg',
  folderPath: 'MyFolder',
  fromRoot: true,
);

if (deleted) {
  print('File deleted successfully');
}

List Files #

// List files in root directory
List<String> files = await storage.listFiles(
  folderPath: 'MyApp/Images',
  fromRoot: true,
);

// List files in DCIM
List<String> files = await storage.listFiles(
  folderPath: 'MyFolder',
  fromRoot: false,
);

print('Found ${files.length} files');
for (String fileName in files) {
  print('File: $fileName');
}

Check File Existence #

bool exists = await storage.fileExists(
  fileName: 'photo.jpg',
  folderPath: 'MyFolder',
  fromRoot: true,
);

if (exists) {
  print('File exists');
}

Save from File Path #

// Save existing file to device storage
bool saved = await storage.saveImageFromPath(
  filePath: '/path/to/image.jpg',
  folderPath: 'MyFolder',
  saveToRoot: true,
);

Open App Settings #

// Open app settings to manually grant permissions
await storage.openSettings();

Complete Example #

import 'package:flutter/material.dart';
import 'package:device_storage/device_storage.dart';
import 'dart:typed_data';

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  final storage = DeviceStorage();
  List<String> fileList = [];

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

  Future<void> _requestPermissions() async {
    await storage.requestPermissions();
  }

  Future<void> _saveFile() async {
    Uint8List bytes = Uint8List.fromList([ /* your data */
    ]);

    String? path = await storage.saveImage(
      imageBytes: bytes,
      fileName: 'test_image.jpg',
      folderPath: 'MyApp',
      saveToRoot: true,
    );

    if (path != null) {
      print('Saved to: $path');
      await _loadFiles();
    }
  }

  Future<void> _loadFiles() async {
    List<String> files = await storage.listFiles(
      folderPath: 'MyApp',
      fromRoot: true,
    );

    setState(() {
      fileList = files;
    });
  }

  Future<void> _deleteFile(String fileName) async {
    bool deleted = await storage.deleteFile(
      fileName: fileName,
      folderPath: 'MyApp',
      fromRoot: true,
    );

    if (deleted) {
      await _loadFiles();
    }
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Device Storage Example')),
        body: Column(
          children: [
            ElevatedButton(
              onPressed: _saveFile,
              child: Text('Save File'),
            ),
            ElevatedButton(
              onPressed: _loadFiles,
              child: Text('Load Files'),
            ),
            Expanded(
              child: ListView.builder(
                itemCount: fileList.length,
                itemBuilder: (context, index) {
                  return ListTile(
                    title: Text(fileList[index]),
                    trailing: IconButton(
                      icon: Icon(Icons.delete),
                      onPressed: () => _deleteFile(fileList[index]),
                    ),
                  );
                },
              ),
            ),
          ],
        ),
      ),
    );
  }
}

Important Notes #

Android 11+ (API 30+) #

For root directory access on Android 11 and above, you need MANAGE_EXTERNAL_STORAGE permission. The app will prompt users to enable "All files access" in settings.

Storage Locations #

  • Root Directory: /storage/emulated/0/YourFolder/
  • DCIM Directory: /storage/emulated/0/DCIM/YourFolder/

File Types #

The package automatically detects MIME types based on file extensions:

  • Images: .jpg, .jpeg, .png, .gif
  • Videos: .mp4, .mov
  • Audio: .mp3, .wav
  • Documents: .pdf, .txt, .json

Troubleshooting #

Permission Denied #

Make sure you've:

  1. Added all required permissions to AndroidManifest.xml
  2. Called requestPermissions() before any operations
  3. For Android 11+, manually enabled "All files access" in app settings

File Not Found #

  • Check if the file exists using fileExists() first
  • Verify the folder path is correct
  • Ensure the file was saved successfully

iOS Issues #

  • Make sure Info.plist has the required photo library permissions
  • iOS doesn't support root directory access - files are saved to app documents

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.

Author #

Md. Mohi-Uddin - [email protected]

Support #

For issues and feature requests, please file an issue on GitHub.

1
likes
140
points
17
downloads

Publisher

unverified uploader

Weekly Downloads

A Flutter plugin for saving, retrieving, and managing files in device storage including root directory and DCIM folder. Supports images, videos, audio, and all file types with easy-to-use API.

Repository (GitHub)
View/report issues

Documentation

API reference

License

Apache-2.0 (license)

Dependencies

flutter, plugin_platform_interface

More

Packages that depend on device_storage

Packages that implement device_storage