### Basic Image Provider Setup Source: https://pub.dev/packages/photo_manager_image_provider/example This snippet shows the essential setup for using the ImageProvider from the photo_manager_image_provider package. It requires importing necessary packages and initializing the ImageManager. ```dart import "package:flutter/material.dart"; import "package:photo_manager_image_provider/photo_manager_image_provider.dart"; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( title: "Photo Manager Image Provider Example", theme: ThemeData( primarySwatch: Colors.blue, ), home: const MyHomePage(), ); } } class MyHomePage extends StatefulWidget { const MyHomePage({super.key}); @override State createState() => _MyHomePageState(); } class _MyHomePageState extends State { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text("Photo Manager Image Provider Example"), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ const Text( "You have pushed the button this many times:", ), // Example of using the ImageProvider FutureBuilder( future: _getAssetEntity(), // Replace with your logic to get an AssetEntity builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.done && snapshot.hasData) { return Image(image: AssetEntityImageProvider(snapshot.data!)); } else if (snapshot.hasError) { return Text("Error loading image: ${snapshot.error}"); } else { return const CircularProgressIndicator(); } }, ) ], ), ), ); } // Placeholder for a method that fetches an AssetEntity Future _getAssetEntity() async { // In a real app, you would use photo_manager to get an AssetEntity // For example: // final List paths = await photoManager.getAssetPathList(); // if (paths.isNotEmpty) { // final List entities = await paths[0].getAssetListRange(start: 0, end: 1); // if (entities.isNotEmpty) { // return entities[0]; // } // } // return null; await Future.delayed(const Duration(seconds: 1)); // Simulate network delay // Return a dummy AssetEntity for demonstration if you don't have photo_manager setup // In a real scenario, this would be a valid AssetEntity object. return null; // Replace with actual AssetEntity retrieval } } ``` -------------------------------- ### Main Application Setup Source: https://pub.dev/packages/photo_manager/example Sets up the main Flutter application, including error handling, system UI styling, and the root widget. It also initializes the PhotoProvider and OKToast for displaying messages. ```dart import 'dart:async'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:oktoast/oktoast.dart'; import 'package:photo_manager/photo_manager.dart'; import 'package:provider/provider.dart'; import 'model/photo_provider.dart'; import 'page/index_page.dart'; import 'widget/image_item_widget.dart'; final PhotoProvider provider = PhotoProvider(); void main() { runZonedGuarded( () => runApp(const _SimpleExampleApp()), (Object e, StackTrace s) { if (kDebugMode) { FlutterError.reportError(FlutterErrorDetails(exception: e, stack: s)); } showToast('$e\n$s', textAlign: TextAlign.start); }, ); SystemChrome.setSystemUIOverlayStyle( const SystemUiOverlayStyle( statusBarColor: Colors.transparent, systemNavigationBarColor: Colors.transparent, ), ); } class _SimpleExampleApp extends StatelessWidget { const _SimpleExampleApp(); @override Widget build(BuildContext context) { return ChangeNotifierProvider.value( value: provider, // This is for the advanced usages. child: MaterialApp( title: 'Photo Manager Example', theme: ThemeData( colorSchemeSeed: Colors.blue, ), themeMode: ThemeMode.system, builder: (context, child) { if (child == null) { return const SizedBox.shrink(); } return Banner( message: 'Debug', location: BannerLocation.bottomStart, child: OKToast(child: child), ); }, home: const _SimpleExamplePage(), debugShowCheckedModeBanner: false, ), ); } } class _SimpleExamplePage extends StatefulWidget { const _SimpleExamplePage(); @override _SimpleExamplePageState createState() => _SimpleExamplePageState(); } class _SimpleExamplePageState extends State<_SimpleExamplePage> { final int _sizePerPage = 50; AssetPathEntity? _path; List? _entities; int _totalEntitiesCount = 0; int _page = 0; bool _isLoading = false; bool _isLoadingMore = false; bool _hasMoreToLoad = true; Future _requestAssets() async { setState(() { _isLoading = true; }); // Request permissions. final PermissionState ps = await PhotoManager.requestPermissionExtend(); if (!mounted) { return; } // Further requests can be only proceed with authorized or limited. if (!ps.hasAccess) { setState(() { _isLoading = false; }); showToast('Permission is not accessible.'); return; } // Customize your own filter options. final PMFilter filter = FilterOptionGroup( imageOption: const FilterOption( sizeConstraint: SizeConstraint(ignoreSize: true), ), ); // Obtain assets using the path entity. final List paths = await PhotoManager.getAssetPathList( onlyAll: true, filterOption: filter, ); if (!mounted) { return; } // Return if not paths found. if (paths.isEmpty) { setState(() { _isLoading = false; }); showToast('No paths found.'); return; } setState(() { _path = paths.first; }); _totalEntitiesCount = await _path!.assetCountAsync; final List entities = await _path!.getAssetListPaged( page: 0, size: _sizePerPage, ); if (!mounted) { return; } setState(() { _entities = entities; _isLoading = false; _hasMoreToLoad = _entities!.length < _totalEntitiesCount; }); } Future _loadMoreAsset() async { final List entities = await _path!.getAssetListPaged( page: _page + 1, size: _sizePerPage, ); if (!mounted) { return; } setState(() { _entities!.addAll(entities); _page++; _hasMoreToLoad = _entities!.length < _totalEntitiesCount; _isLoadingMore = false; }); } ``` -------------------------------- ### Getting Asset List Paged Source: https://pub.dev/packages/photo_manager Fetches a paginated list of media assets (`AssetEntity`) from a specific album or folder. ```APIDOC ## Getting Asset List Paged ### Description Retrieves a paginated list of media assets (`AssetEntity`) from an `AssetPathEntity`. ### Method `path.getAssetListPaged(int page, int size)` ### Parameters * `page` (int) - The page number to retrieve. * `size` (int) - The number of assets per page. ### Response * `List` - A list of media assets. ``` -------------------------------- ### Get Asset Count Source: https://pub.dev/packages/photo_manager Retrieves the total number of media assets available on the device. ```APIDOC ## Get Asset Count ### Description Retrieves the total number of media assets available on the device. ### Method `GET` (conceptual) ### Endpoint `PhotoManager.getAssetCount()` ### Response #### Success Response - **count** (int) - The total number of assets. ``` -------------------------------- ### Get Asset List by Range Source: https://pub.dev/packages/photo_manager Retrieve a specific range of assets. Useful for precise asset selection. ```dart final List entities = await PhotoManager.getAssetListRange(start: 0, end: 80); ``` -------------------------------- ### Getting Asset List Range Source: https://pub.dev/packages/photo_manager Fetches a list of media assets (`AssetEntity`) within a specified range from a specific album or folder. ```APIDOC ## Getting Asset List Range ### Description Retrieves a list of media assets (`AssetEntity`) within a specified range (start and end index) from an `AssetPathEntity`. ### Method `path.getAssetListRange(int start, int end)` ### Parameters * `start` (int) - The starting index of the range. * `end` (int) - The ending index of the range. ### Response * `List` - A list of media assets. ``` -------------------------------- ### Get Assets from Album Path (Range) Source: https://pub.dev/packages/photo_manager Retrieve a list of assets (AssetEntity) from an album path using a start and end index. This method is useful for fetching a specific range of assets. ```dart final List entities = await path.getAssetListRange(start: 0, end: 80); ``` -------------------------------- ### Getting Current Permission State Source: https://pub.dev/packages/photo_manager Retrieves the current state of media access permission. ```APIDOC ## Getting Current Permission State ### Description Retrieves the current permission state without requesting it. Ensure the same permission request options are used here as with other asset requests. ### Method `PhotoManager.getPermissionState()` ### Response * `PermissionState` - The current permission state. ``` -------------------------------- ### Get Asset Count Source: https://pub.dev/packages/photo_manager Retrieve the total number of assets available in the photo library. ```dart final int count = await PhotoManager.getAssetCount(); ``` -------------------------------- ### Get Asset List Range Source: https://pub.dev/packages/photo_manager Retrieves a list of assets within a specified range of indices. ```APIDOC ## Get Asset List Range ### Description Retrieves a list of assets within a specified range of indices. This is an alternative to pagination for fetching specific subsets of assets. ### Method `GET` (conceptual) ### Endpoint `PhotoManager.getAssetListRange(start: int, end: int)` ### Parameters #### Query Parameters - **start** (int) - Required - The starting index of the range (inclusive, starts from 0). - **end** (int) - Required - The ending index of the range (exclusive). ``` -------------------------------- ### Get Assets from Album Path (Paged) Source: https://pub.dev/packages/photo_manager Fetch a paginated list of assets (AssetEntity) from a specific album path. Specify the page number and the desired size of the page. ```dart final List entities = await path.getAssetListPaged(page: 0, size: 80); ``` -------------------------------- ### Get Asset List Paged Source: https://pub.dev/packages/photo_manager Retrieves a list of assets using pagination, suitable for loading assets in batches. ```APIDOC ## Get Asset List Paged ### Description Retrieves a list of assets using pagination. This method is useful for loading assets in batches to manage memory and improve performance. ### Method `GET` (conceptual) ### Endpoint `PhotoManager.getAssetListPaged(page: int, pageCount: int)` ### Parameters #### Query Parameters - **page** (int) - Required - The page number to retrieve (starts from 0). - **pageCount** (int) - Required - The number of assets to retrieve per page. ``` -------------------------------- ### Getting Asset Path List Source: https://pub.dev/packages/photo_manager Retrieves a list of albums or folders, represented by `AssetPathEntity`, from the user's media library. ```APIDOC ## Getting Asset Path List ### Description Retrieves a list of albums or folders (`AssetPathEntity`) from the media library. These correspond to `MediaStore` on Android and `PHAssetCollection` on iOS/macOS. ### Method `PhotoManager.getAssetPathList()` ### Parameters * `hasAll` (bool) - Optional - Set to `true` to include an album containing all assets. Defaults to `true`. * `onlyAll` (bool) - Optional - If `true`, only returns the album containing all assets. Defaults to `false`. * `type` (RequestType) - Optional - Specifies the type of media resource (e.g., video, image, audio). Defaults to `RequestType.common`. * `filterOption` (FilterOptionGroup) - Optional - Used to filter resource files. See Filtering for details. * `pathFilterOption` (PMPathFilter) - Optional - Only valid for iOS and macOS, for the corresponding album type. See PMPathFilterOption for more detail. Defaults to including all paths. ### Response * `List` - A list of album/folder entities. ``` -------------------------------- ### Import photo_manager in Dart Code Source: https://pub.dev/packages/photo_manager/install Import the photo_manager package into your Dart files to start using its APIs. ```dart import 'package:photo_manager/photo_manager.dart'; ``` -------------------------------- ### Get Asset List Paged Source: https://pub.dev/packages/photo_manager Fetch a list of assets using pagination. Useful for displaying assets in a scrollable view. ```dart final List entities = await PhotoManager.getAssetListPaged(page: 0, pageCount: 80); ``` -------------------------------- ### Get All Album Paths Source: https://pub.dev/packages/photo_manager Retrieve a list of all album paths (AssetPathEntity) available in the photo library. This method can be configured with options to include all assets or filter by media type. ```dart final List paths = await PhotoManager.getAssetPathList(); ``` -------------------------------- ### Basic Flutter App Structure Source: https://pub.dev/packages/photo_manager_image_provider/example This is the main entry point and root widget of a typical Flutter application. It sets up the MaterialApp, theme, and navigates to the home page. ```dart import 'package:flutter/material.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); // This widget is the root of your application. @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( // This is the theme of your application. // // TRY THIS: Try running your application with "flutter run". You'll see // the application has a blue toolbar. Then, without quitting the app, // try changing the seedColor in the colorScheme below to Colors.green // and then invoke "hot reload" (save your changes or press the "hot // reload" button in a Flutter-supported IDE, or press "r" if you used // the command line to start the app). // // Notice that the counter didn't reset back to zero; the application // state is not lost during the reload. To reset the state, use hot // restart instead. // // This works for code too, not just values: Most code changes can be // tested with just a hot reload. colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), useMaterial3: true, ), home: const MyHomePage(title: 'Flutter Demo Home Page'), ); } } class MyHomePage extends StatefulWidget { const MyHomePage({super.key, required this.title}); // This widget is the home page of your application. It is stateful, meaning // that it has a State object (defined below) that contains fields that affect // how it looks. // This class is the configuration for the state. It holds the values (in this // case the title) provided by the parent (in this case the App widget) and // used by the build method of the State. Fields in a Widget subclass are // always marked "final". final String title; @override State createState() => _MyHomePageState(); } class _MyHomePageState extends State { int _counter = 0; void _incrementCounter() { setState(() { // This call to setState tells the Flutter framework that something has // changed in this State, which causes it to rerun the build method below // so that the display can reflect the updated values. If we changed // _counter without calling setState(), then the build method would not be // called again, and so nothing would appear to happen. _counter++; }); } @override Widget build(BuildContext context) { // This method is rerun every time setState is called, for instance as done // by the _incrementCounter method above. // // The Flutter framework has been optimized to make rerunning build methods // fast, so that you can just rebuild anything that needs updating rather // than having to individually change instances of widgets. return Scaffold( appBar: AppBar( // TRY THIS: Try changing the color here to a specific color (to // Colors.amber, perhaps?) and trigger a hot reload to see the AppBar // change color while the other colors stay the same. backgroundColor: Theme.of(context).colorScheme.inversePrimary, // Here we take the value from the MyHomePage object that was created by // the App.build method, and use it to set our appbar title. title: Text(widget.title), ), body: Center( // Center is a layout widget. It takes a single child and positions it // in the middle of the parent. child: Column( // Column is also a layout widget. It takes a list of children and // arranges them vertically. By default, it sizes itself to fit its // children horizontally, and tries to be as tall as its parent. // // Column has various properties to control how it sizes itself and // how it positions its children. Here we use mainAxisAlignment to // center the children vertically; the main axis here is the vertical // axis because Columns are vertical (the cross axis would be // horizontal). // // TRY THIS: Invoke "debug painting" (choose the "Toggle Debug Paint" // action in the IDE, or press "p" in the console), to see the // wireframe for each widget. mainAxisAlignment: MainAxisAlignment.center, children: [ const Text( 'You have pushed the button this many times:', ), Text( '$_counter', style: Theme.of(context).textTheme.headlineMedium, ), ], ), ), floatingActionButton: FloatingActionButton( onPressed: _incrementCounter, tooltip: 'Increment', child: const Icon(Icons.add), ), // This trailing comma makes auto-formatting nicer for build methods. ); } } ``` -------------------------------- ### Create Album (Darwin) Source: https://pub.dev/packages/photo_manager Creates a new album on iOS or macOS. The parent can be null for the root path or another accessible folder. ```dart PhotoManager.editor.darwin.createAlbum( name, parent: parent, ); ``` -------------------------------- ### Create Folder (Darwin) Source: https://pub.dev/packages/photo_manager Creates a new folder on iOS or macOS. The parent can be null for the root path or another accessible folder. ```dart PhotoManager.editor.darwin.createFolder( name, parent: parent, ); ``` -------------------------------- ### Add photo_manager_image_provider to Dependencies Source: https://pub.dev/packages/photo_manager_image_provider Add the package to your pubspec.yaml file to include it in your project. ```yaml dependencies: photo_manager_image_provider: #version ``` -------------------------------- ### Create CustomFilter with SQL-like WHERE and ORDER BY Source: https://pub.dev/packages/photo_manager Creates a CustomFilter using SQL-like syntax for filtering assets based on width and height, and ordering them by creation date. This is suitable for platform-specific filtering needs. ```dart CustomFilter createFilter() { final filter = CustomFilter.sql( where: '${CustomColumns.base.width} > 100 AND ${CustomColumns.base.height} > 200', orderBy: [OrderByItem.desc(CustomColumns.base.createDate)], ); // Include hidden assets in the results (iOS only) filter.includeHiddenAssets = true; return filter; } ``` -------------------------------- ### Create FilterOptionGroup Source: https://pub.dev/packages/photo_manager Constructs a FilterOptionGroup with specific criteria for image size, video duration, creation time, and sorting order. Use this for filtering assets based on predefined options. ```dart final FilterOptionGroup filterOption = FilterOptionGroup( imageOption: FilterOption( sizeConstraint: SizeConstraint( maxWidth: 10000, maxHeight: 10000, minWidth: 100, minHeight: 100, ignoreSize: false, ), ), videoOption: FilterOption( durationConstraint: DurationConstraint( min: Duration(seconds: 1), max: Duration(seconds: 30), allowNullable: false, ), ), createTimeCondition: DateTimeCondition( min: DateTime(2020, 1, 1), max: DateTime(2020, 12, 31), ), orders: [ OrderOption( type: OrderOptionType.createDate, asc: false, ), ], /// Include hidden assets in the results (iOS only) includeHiddenAssets: false, /// other options ); ``` -------------------------------- ### Preload Thumbnails with PhotoCachingManager Source: https://pub.dev/packages/photo_manager Initiates the preloading of thumbnails for assets using specified options. This can improve perceived performance when displaying assets. ```dart PhotoCachingManager().requestCacheAssets(assets: assets, option: option); ``` -------------------------------- ### Presenting Limited Photos Library Management (iOS) Source: https://pub.dev/packages/photo_manager Opens the system's interface for users to manage which photos their app can access when limited access is granted. ```APIDOC ## Presenting Limited Photos Library Management (iOS) ### Description Opens the modal for managing accessible entities when the app has limited photo library access on iOS 14+. This method is only available when the permission state is `PermissionState.limited`. ### Method `PhotoManager.presentLimited()` ### Availability * iOS 14+ and when `PermissionState.limited`. ### Usage Example ```dart await PhotoManager.presentLimited(); ``` ``` -------------------------------- ### Display Assets with AssetEntityImage Source: https://pub.dev/packages/photo_manager Use AssetEntityImage to display assets. Configure thumbnail size and format for preferred display. ```dart import 'package:photo_manager_image_provider/photo_manager_image_provider.dart'; final Widget image = AssetEntityImage( yourAssetEntity, isOriginal: false, // Defaults to `true`. thumbnailSize: const ThumbnailSize.square(200), // Preferred value. thumbnailFormat: ThumbnailFormat.jpeg, // Defaults to `jpeg`. ); final Widget imageFromProvider = Image( image: AssetEntityImageProvider( yourAssetEntity, isOriginal: false, thumbnailSize: const ThumbnailSize.square(200), thumbnailFormat: ThumbnailFormat.jpeg, ), ); ``` -------------------------------- ### Add photo_manager_image_provider to Flutter Project Source: https://pub.dev/packages/photo_manager_image_provider/install Run this command in your terminal to add the package as a dependency. This command automatically updates your pubspec.yaml file. ```bash $ flutter pub add photo_manager_image_provider ``` -------------------------------- ### Add Plugin to pubspec.yaml Source: https://pub.dev/packages/photo_manager Add the photo_manager plugin to your project's dependencies in pubspec.yaml. ```yaml dependencies: photo_manager: $latest_version ``` -------------------------------- ### Build Body Widget for Photo Manager Source: https://pub.dev/packages/photo_manager/example Builds the main body of the photo manager UI, displaying assets in a grid or loading indicators. Handles initial loading, empty states, and infinite scrolling. ```dart Widget _buildBody(BuildContext context) { if (_isLoading) { return const Center(child: CircularProgressIndicator.adaptive()); } final entities = _entities; if (entities == null) { return const Center(child: Text('Click buttons to request assets.')); } if (entities.isEmpty) { return const Center(child: Text('No assets found on this device.')); } return GridView.custom( gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 4, ), childrenDelegate: SliverChildBuilderDelegate( (BuildContext context, int index) { if (index == entities.length - 8 && !_isLoadingMore && _hasMoreToLoad) { _loadMoreAsset(); } final AssetEntity entity = entities[index]; return ImageItemWidget( key: ValueKey(index), entity: entity, option: const ThumbnailOption(size: ThumbnailSize.square(200)), ); }, childCount: entities.length, findChildIndexCallback: (Key key) { // Re-use elements. if (key is ValueKey) { return key.value; } return null; }, ), ); } ``` ```dart @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('photo_manager')), body: Column( children: [ const Padding( padding: EdgeInsets.all(8.0), child: Text( 'This page will only obtain the first page of assets ' 'under the primary album (a.k.a. Recent). ' 'If you want more filtering assets, ' 'head over to "Advanced usages".', ), ), Expanded(child: _buildBody(context)), ], ), persistentFooterButtons: [ TextButton( onPressed: () { Navigator.of(context).push( MaterialPageRoute(builder: (_) => const IndexPage()), ); }, child: const Text('Advanced usages'), ), ], floatingActionButton: FloatingActionButton( onPressed: _requestAssets, child: const Icon(Icons.developer_board), ), ); } ``` -------------------------------- ### Define Darwin Path Filter Options Source: https://pub.dev/packages/photo_manager Create a PMDarwinPathFilter to specify desired album types and subtypes for iOS and macOS. This allows for granular control over which collections are retrieved. ```dart final List pathTypeList = []; // use your need type final List pathSubTypeList = []; // use your need type final darwinPathFilterOption = PMDarwinPathFilter( type: pathTypeList, subType: pathSubTypeList, ); PMPathFilter pathFilter = PMPathFilter(); ``` -------------------------------- ### Filter Live Photos using CustomSqlFilter Source: https://pub.dev/packages/photo_manager Alternatively, filter for Live Photos using a custom SQL query targeting media type and subtypes. ```dart final List paths = await PhotoManager.getAssetPathList( type: RequestType.image, filterOption: CustomFilter.sql( where: '${CustomColumns.base.mediaType} = 1' ' AND ' '${CustomColumns.darwin.mediaSubtypes} & (1 << 3) = (1 << 3)', ), ); ``` -------------------------------- ### Display AssetEntity with AssetEntityImage Widget Source: https://pub.dev/packages/photo_manager_image_provider Use the convenience widget AssetEntityImage for a simpler way to display an image from an AssetEntity. ```dart Widget buildWidget(AssetEntity entity) { return AssetEntityImage(entity); } ``` -------------------------------- ### Add photo_manager Dependency Source: https://pub.dev/packages/photo_manager/install Run this command to add the photo_manager package to your Flutter project. This automatically updates your pubspec.yaml file. ```bash $ flutter pub add photo_manager ``` -------------------------------- ### Add Android 13 Media Permissions Source: https://pub.dev/packages/photo_manager For Android 13 (API 33), add these permissions to your manifest to specify access to images, videos, or audio. ```xml ``` -------------------------------- ### Configure Limited Photo Library Access (iOS) Source: https://pub.dev/packages/photo_manager Add a key to your app's Info.plist to prevent the system from automatically prompting for limited photo library access alerts when the app restarts. ```xml PHPhotoLibraryPreventAutomaticLimitedAccessAlert ``` -------------------------------- ### Requesting Media Permission Source: https://pub.dev/packages/photo_manager Requests permission to access user's media library. It's recommended to check the permission state before proceeding with media operations. ```APIDOC ## Requesting Media Permission ### Description Requests permission to access user's media library. The method `requestPermissionExtend` can be used with an optional `permission` parameter. It returns a `PermissionState` object which indicates the authorization status. ### Method `PhotoManager.requestPermissionExtend()` ### Parameters * `permission` (PermissionState) - Optional - The specific permission to request. ### Response * `PermissionState` - An object indicating the authorization status (e.g., `isAuth`, `hasAccess`, `limited`). ### Usage Example ```dart final PermissionState ps = await PhotoManager.requestPermissionExtend(); if (ps.isAuth) { // Granted } else if (ps.hasAccess) { // Access will continue, but the amount visible depends on the user's selection. } else { // Limited or Rejected // Consider calling PhotoManager.openSetting() } ``` ``` -------------------------------- ### iOS Info.plist Configuration for Photo Library Access Source: https://pub.dev/packages/photo_manager Define the NSPhotoLibraryUsageDescription key in your iOS Info.plist to request permission for accessing the photo library. ```xml NSPhotoLibraryUsageDescription In order to access your photo library ``` -------------------------------- ### Register and Manage Photo Manager Change Callbacks Source: https://pub.dev/packages/photo_manager Use these methods to subscribe to and unsubscribe from entity change events. Ensure you enable notifications after registering callbacks and disable them when no longer needed. ```dart import 'package:flutter/services.dart'; void changeNotify(MethodCall call) { // Your custom callback. } /// Register your callback. PhotoManager.addChangeCallback(changeNotify); /// Enable change notify. PhotoManager.startChangeNotify(); /// Remove your callback. PhotoManager.removeChangeCallback(changeNotify); /// Disable change notify. PhotoManager.stopChangeNotify(); ``` -------------------------------- ### Save Image from Path Source: https://pub.dev/packages/photo_manager Saves an image to the device's media gallery from a file path. ```APIDOC ## Save Image from Path ### Description Saves an image to the device's media gallery by copying it from a given file path. This method is akin to a copy operation. ### Method `POST` (conceptual) ### Endpoint `PhotoManager.editor.saveImageWithPath(path: String, title: String?)` ### Parameters #### Request Body - **path** (String) - Required - The absolute path to the source image file. - **title** (String) - Optional - The title for the image. ### Response #### Success Response - **imageEntityWithPath** (AssetEntity?) - The created asset entity, or null if saving failed. ``` -------------------------------- ### Save Video from File Source: https://pub.dev/packages/photo_manager Save a video to the photo library from a File object. It's recommended to check file existence. ```dart final File videoFile = File('path/to/your/video.mp4'); final AssetEntity? videoEntity = await PhotoManager.editor.saveVideo( videoFile, // You can check whether the file is exist for better test coverage. title: 'write_your_own_title.mp4', ); ``` -------------------------------- ### Add Android 14 Media Permissions Source: https://pub.dev/packages/photo_manager When targeting Android 14 (API 34), include this permission in your manifest to allow access to user-selected media. ```xml ``` -------------------------------- ### Save Image from Path Source: https://pub.dev/packages/photo_manager Save an image to the photo library from its file path. This operation acts like a copy. ```dart final AssetEntity? imageEntityWithPath = await PhotoManager.editor.saveImageWithPath( path, // Use the absolute path of your source file, it's more like a copy method. title: 'same_as_above.jpg', ); ``` -------------------------------- ### Request Photo Library Permission Source: https://pub.dev/packages/photo_manager Request extended permission for the photo library. Check the permission state to determine access level and handle cases where access is limited or rejected by opening the settings. ```dart final PermissionState ps = await PhotoManager.requestPermissionExtend(); // the method can use optional param `permission`. if (ps.isAuth) { // Granted // You can to get assets here. } else if (ps.hasAccess) { // Access will continue, but the amount visible depends on the user's selection. } else { // Limited(iOS) or Rejected, use `==` for more precise judgements. // You can call `PhotoManager.openSetting()` to open settings for further steps. } ``` -------------------------------- ### Save Video from File Source: https://pub.dev/packages/photo_manager Saves a video to the device's media gallery from a File object. ```APIDOC ## Save Video from File ### Description Saves a video to the device's media gallery from a `File` object. It's recommended to check for file existence before calling this method. ### Method `POST` (conceptual) ### Endpoint `PhotoManager.editor.saveVideo(videoFile: File, title: String?)` ### Parameters #### Request Body - **videoFile** (File) - Required - The video file to save. - **title** (String) - Optional - The title for the video. ### Response #### Success Response - **videoEntity** (AssetEntity?) - The created asset entity, or null if saving failed. ``` -------------------------------- ### Move Assets to Trash (Android) Source: https://pub.dev/packages/photo_manager Moves specified assets to the trash on Android 11 and above. Throws an exception on older versions. ```dart await PhotoManager.editor.android.moveToTrash(list); ``` -------------------------------- ### Obtain Video from Live Photos Source: https://pub.dev/packages/photo_manager Retrieve media URLs and files for Live Photos, including original and subtype-specific files. Supports converting Live Photo video from MOV to MP4. ```dart final AssetEntity entity = livePhotoEntity; // To play Live Photo's video. final String? mediaUrl = await entity.getMediaUrl(); // Get files for normal displays like thumbnails. final File? imageFile = await entity.file; final File? videoFile = await entity.fileWithSubtype; // Get files for the raw displays like detail preview. final File? originImageFile = await entity.originFile; final File? originVideoFile = await entity.originFileWithSubtype; // Additionally, you can convert Live Photo's (on iOS) video file // from `mov` to `mp4` using: final File? convertedFile = await entity.loadFile( isOriginal: true, withSubtye: true, darwinFileType: PMDarwinAVFileType.mp4, ); ``` -------------------------------- ### Create AdvancedCustomFilter with WHERE condition group Source: https://pub.dev/packages/photo_manager Constructs an AdvancedCustomFilter by defining a group of WHERE conditions (AND/OR) and specifying the order of results. This provides a more structured way to build complex filters. ```dart CustomFilter createFilter() { final group = WhereConditionGroup() .and( ColumnWhereCondition( column: CustomColumns.base.width, value: '100', operator: '>', ), ) .or( ColumnWhereCondition( column: CustomColumns.base.height, value: '200', operator: '>', ), ); final filter = AdvancedCustomFilter() .addWhereCondition(group) .addOrderBy(column: CustomColumns.base.createDate, isAsc: false); return filter; } ``` -------------------------------- ### Filter Live Photos using FilterOptionGroup Source: https://pub.dev/packages/photo_manager Obtain only Live Photos by setting `onlyLivePhotos: true` in FilterOptionGroup when requesting asset paths. ```dart final List paths = await PhotoManager.getAssetPathList( type: RequestType.image, filterOption: FilterOptionGroup(onlyLivePhotos: true), ); ``` -------------------------------- ### Import photo_manager_image_provider in Dart Code Source: https://pub.dev/packages/photo_manager_image_provider/install Use this import statement in your Dart files to access the package's functionalities. ```dart import 'package:photo_manager_image_provider/photo_manager_image_provider.dart'; ``` -------------------------------- ### Save Live Photo (iOS Only) Source: https://pub.dev/packages/photo_manager Save a live photo to the photo library using separate image and video files. Requires both files to be part of the same live photo. ```dart // [iOS only] Save a live photo from image and video `File`. // This only works when both image and video file were part of same live photo. final File imageFile = File('path/to/your/live_photo.heic'); final File videoFile = File('path/to/your/live_video.mp4'); final AssetEntity? entity = await PhotoManager.editor.darwin.saveLivePhoto( imageFile: imageFile, videoFile: videoFile, title: 'write_your_own_title.heic', ); ``` -------------------------------- ### Manage Cached File on iOS Source: https://pub.dev/packages/photo_manager This snippet demonstrates how to obtain a file from an AssetEntity and handle potential deletion of the cached file on iOS after usage. It's useful when disk space is a concern on iOS. ```dart import 'dart:io'; Future useEntity(AssetEntity entity) async { File? file; try { file = await entity.file; await handleFile(file!); // Custom method to handle the obtained file. } finally { if (Platform.isIOS) { file?.deleteSync(); // Delete it once the process has done. } } } ``` -------------------------------- ### Retrieve Asset by ID Source: https://pub.dev/packages/photo_manager Retrieves an AssetEntity using its unique identifier. ```APIDOC ## Retrieve Asset by ID ### Description Retrieves an `AssetEntity` using its unique identifier. This is useful for re-accessing previously persisted assets. ### Method `GET` (conceptual) ### Endpoint `AssetEntity.fromId(id: String)` ### Parameters #### Path Parameters - **id** (String) - Required - The unique identifier of the asset. ### Response #### Success Response - **asset** (AssetEntity?) - The retrieved asset entity, or null if not found or accessible. ``` -------------------------------- ### Android Manifest Configuration for Scoped Storage Source: https://pub.dev/packages/photo_manager Configure AndroidManifest.xml with requestLegacyExternalStorage for Android 10 (API 29) if not using higher target SDKs. Note that this flag may cause rejection from Google Play. ```xml ``` -------------------------------- ### Save Live Photo (iOS Only) Source: https://pub.dev/packages/photo_manager Saves a Live Photo to the device's media gallery from separate image and video files. ```APIDOC ## Save Live Photo (iOS Only) ### Description Saves a Live Photo to the device's media gallery on iOS, using separate image and video files that constitute the Live Photo. This method requires both files to be part of the same Live Photo. ### Method `POST` (conceptual) ### Endpoint `PhotoManager.editor.darwin.saveLivePhoto(imageFile: File, videoFile: File, title: String?)` ### Parameters #### Request Body - **imageFile** (File) - Required - The image file (e.g., HEIC) of the Live Photo. - **videoFile** (File) - Required - The video file (e.g., MP4) of the Live Photo. - **title** (String) - Optional - The title for the Live Photo. ### Response #### Success Response - **entity** (AssetEntity?) - The created asset entity, or null if saving failed. Note that iOS may impose limitations on file types that can be saved as media assets. ``` -------------------------------- ### Display AssetEntity with ImageProvider Source: https://pub.dev/packages/photo_manager_image_provider Use AssetEntityImageProvider to load an image from an AssetEntity. This is the fundamental way to integrate with Flutter's Image widget. ```dart import 'package:photo_manager/photo_manager.dart'; import 'package:photo_manager_image_provider/photo_manager_image_provider.dart'; Widget buildWidget(AssetEntity entity) { return Image( image: AssetEntityImageProvider(entity), ); } ``` -------------------------------- ### Save Image from Raw Data Source: https://pub.dev/packages/photo_manager Saves an image to the device's media gallery from raw byte data. ```APIDOC ## Save Image from Raw Data ### Description Saves an image to the device's media gallery from raw byte data (`Uint8List`). The saved image will appear in the gallery app. ### Method `POST` (conceptual) ### Endpoint `PhotoManager.editor.saveImage(rawData: Uint8List, title: String?)` ### Parameters #### Request Body - **rawData** (Uint8List) - Required - The raw byte data of the image. - **title** (String) - Optional - The title for the image, which may affect EXIF reading. ### Response #### Success Response - **entity** (AssetEntity?) - The created asset entity, or null if saving failed. ```